Skip to content

Commit

Permalink
[#1802] Adjust code to Jetty 12 SNAPSHOT (20230627)
Browse files Browse the repository at this point in the history
  • Loading branch information
grgrzybek committed Jun 27, 2023
1 parent de2df6d commit 9c505ac
Show file tree
Hide file tree
Showing 11 changed files with 217 additions and 229 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@
import jakarta.servlet.SessionCookieConfig;
import jakarta.servlet.annotation.ServletSecurity;
import jakarta.servlet.http.HttpSessionAttributeListener;
import org.eclipse.jetty.ee.security.ConstraintAware;
import org.eclipse.jetty.ee.security.ConstraintMapping;
import org.eclipse.jetty.ee10.servlet.ErrorPageErrorHandler;
import org.eclipse.jetty.ee10.servlet.FilterHolder;
import org.eclipse.jetty.ee10.servlet.FilterMapping;
Expand All @@ -34,6 +32,8 @@
import org.eclipse.jetty.ee10.servlet.ServletHolder;
import org.eclipse.jetty.ee10.servlet.ServletMapping;
import org.eclipse.jetty.ee10.servlet.SessionHandler;
import org.eclipse.jetty.ee10.servlet.security.ConstraintAware;
import org.eclipse.jetty.ee10.servlet.security.ConstraintMapping;
import org.eclipse.jetty.ee10.servlet.security.ConstraintSecurityHandler;
import org.eclipse.jetty.http.HttpCookie;
import org.eclipse.jetty.http.PreEncodedHttpField;
Expand Down Expand Up @@ -754,11 +754,11 @@ public void visitServletContextModelChange(ServletContextModelChange change) {

LOG.info("Creating new Jetty context for {}", model);

PaxWebServletContextHandler sch = new PaxWebServletContextHandler(null, contextPath, configuration);
PaxWebServletContextHandler sch = new PaxWebServletContextHandler(contextPath, configuration);
// special, OSGi-aware org.eclipse.jetty.servlet.ServletHandler
sch.setServletHandler(new PaxWebServletHandler(default404Servlet, new OsgiSessionAttributeListener(sessionListenerModels)));
// setting "false" here will trigger 302 redirect when browsing to context without trailing "/"
sch.setAllowNullPathInfo(false);
sch.setAllowNullPathInContext(false);
// welcome files will be handled at default/resource servlet level and OsgiServletContext
sch.setWelcomeFiles(new String[0]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,11 @@ public class PaxWebServletContextHandler extends ServletContextHandler {
* {@code org.eclipse.jetty.webapp.WebAppContext} which does all the sort of XML/annotation configuration, but
* we take some of the mechanisms from {@code WebAppContext} if they're useful in Pax Web.
*
* @param parent
* @param contextPath
* @param configuration
*/
public PaxWebServletContextHandler(Handler.Container parent, String contextPath, Configuration configuration) {
super(parent, contextPath, true, true);
public PaxWebServletContextHandler(String contextPath, Configuration configuration) {
super(contextPath, true, true);

// TCCL of sessionManager timer threads will be set to thread of pax-web-jetty bundle, not to current TCCL
ScheduledExecutorScheduler executorScheduler = new ScheduledExecutorScheduler(getSessionHandler().toString() + "Timer", true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
package org.ops4j.pax.web.service.jetty.internal;

import org.eclipse.jetty.ee10.servlet.ServletContextRequest;
import org.eclipse.jetty.ee10.servlet.ServletHandler;
import org.eclipse.jetty.http.pathmap.MatchedResource;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.session.DefaultSessionIdManager;
Expand All @@ -34,7 +36,8 @@ public PaxWebSessionIdManager(Server server) {

public static String getSessionIdSuffix(Request r) {
ServletContextRequest req = Request.as(r, ServletContextRequest.class);
if (req.getMappedServlet() != null && req.getMappedServlet().getServletHolder() instanceof PaxWebServletHolder holder) {
MatchedResource<ServletHandler.MappedServlet> match = req.getMatchedResource();
if (match != null && match.getResource() != null && match.getResource().getServletHolder() instanceof PaxWebServletHolder holder) {
OsgiContextModel ocm = holder.getOsgiContextModel();
// we can't replace '/' to '_' because of how
// org.eclipse.jetty.server.session.FileSessionDataStore.initializeStore() analyzes the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

package org.ops4j.pax.web.service.jetty.internal.web;

//CHECKSTYLE:OFF
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
Expand All @@ -33,8 +32,6 @@
import java.util.Set;
import java.util.StringTokenizer;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;

Expand All @@ -48,7 +45,6 @@
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpServletResponseWrapper;
import org.eclipse.jetty.ee10.servlet.ServletApiRequest;
import org.eclipse.jetty.ee10.servlet.ServletApiResponse;
import org.eclipse.jetty.ee10.servlet.ServletContextHandler;
import org.eclipse.jetty.ee10.servlet.ServletContextRequest;
import org.eclipse.jetty.ee10.servlet.ServletContextResponse;
Expand All @@ -71,13 +67,17 @@
import org.eclipse.jetty.io.ByteBufferInputStream;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.server.Context;
import org.eclipse.jetty.server.HttpStream;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.ResourceService;
import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.*;
import org.eclipse.jetty.util.Blocker;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.util.resource.ResourceFactory;
import org.eclipse.jetty.util.resource.Resources;
Expand Down Expand Up @@ -227,7 +227,7 @@ public void init() throws ServletException
}
}

// for welcome file handling we need some _baseResource
// Pax Web: for welcome file handling we need some _baseResource
_baseResource = configureBaseResource();

List<CompressedContentFormat> precompressedFormats = parsePrecompressedFormats(getInitParameter("precompressed"),
Expand All @@ -238,7 +238,7 @@ public void init() throws ServletException
if (contentFactory == null)
{
MimeTypes mimeTypes = _contextHandler.getMimeTypes();
// we need to translate "" to "/", so this::getResource is not enough
// Pax Web: we need to translate "" to "/", so this::getResource is not enough
// also we want to use LaxResourceFactory whether or not _baseResource is set (it has to be set for
// proper welcome file handling)
// ResourceFactory resourceFactory = _baseResource != null ? ResourceFactory.of(_baseResource) : this::getResource;
Expand Down Expand Up @@ -299,6 +299,7 @@ public void init() throws ServletException

_resourceService.setAcceptRanges(getInitBoolean("acceptRanges", _resourceService.isAcceptRanges()));
_resourceService.setDirAllowed(getInitBoolean("dirAllowed", _resourceService.isDirAllowed()));
// Pax Web: use preconfigured value of redirectWelcome flag
boolean redirectWelcome = getInitBoolean("redirectWelcome", this.redirectWelcome);
_resourceService.setWelcomeMode(redirectWelcome ? ResourceService.WelcomeMode.REDIRECT : ResourceService.WelcomeMode.SERVE);
_resourceService.setPrecompressedFormats(precompressedFormats);
Expand Down Expand Up @@ -477,7 +478,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws Se
else if (isPathInfoOnly())
encodedPathInContext = URIUtil.encodePath(req.getPathInfo());
else if (req instanceof ServletApiRequest apiRequest)
encodedPathInContext = Context.getPathInContext(req.getContextPath(), apiRequest.getServletContextRequest().getHttpURI().getCanonicalPath());
encodedPathInContext = Context.getPathInContext(req.getContextPath(), apiRequest.getRequest().getHttpURI().getCanonicalPath());
else
encodedPathInContext = Context.getPathInContext(req.getContextPath(), URIUtil.canonicalPath(req.getRequestURI()));

Expand Down Expand Up @@ -509,7 +510,7 @@ else if (req instanceof ServletApiRequest apiRequest)
else
{
ServletCoreRequest coreRequest = new ServletCoreRequest(req);
ServletCoreResponse coreResponse = new ServletCoreResponse(coreRequest, resp);
ServletCoreResponse coreResponse = new ServletCoreResponse(coreRequest, resp, included);

if (coreResponse.isCommitted())
{
Expand Down Expand Up @@ -649,17 +650,6 @@ public boolean isSecure()
return _servletRequest.isSecure();
}

@Override
public boolean addErrorListener(Predicate<Throwable> onError)
{
return false;
}

@Override
public void addHttpStreamWrapper(Function<HttpStream, HttpStream> wrapper)
{
}

@Override
public Object removeAttribute(String name)
{
Expand Down Expand Up @@ -891,13 +881,34 @@ private static class ServletCoreResponse implements Response
private final ServletCoreRequest _coreRequest;
private final Response _coreResponse;
private final HttpFields.Mutable _httpFields;
private final boolean _included;

public ServletCoreResponse(ServletCoreRequest coreRequest, HttpServletResponse response)
public ServletCoreResponse(ServletCoreRequest coreRequest, HttpServletResponse response, boolean included)
{
_coreRequest = coreRequest;
_response = response;
_coreResponse = ServletContextResponse.getServletContextResponse(response);
_httpFields = new HttpServletResponseHttpFields(response);
HttpFields.Mutable fields = new HttpServletResponseHttpFields(response);
if (included)
{
// If included, accept but ignore mutations.
fields = new HttpFields.Mutable.Wrapper(fields)
{
@Override
public HttpField onAddField(HttpField field)
{
return null;
}

@Override
public boolean onRemoveField(HttpField field)
{
return false;
}
};
}
_httpFields = fields;
_included = included;
}

@Override
Expand All @@ -908,12 +919,7 @@ public HttpFields.Mutable getHeaders()

public ServletContextResponse getServletContextResponse()
{
if (_response instanceof ServletApiResponse)
{
ServletApiResponse apiResponse = (ServletApiResponse)_response;
return apiResponse.getResponse();
}
return null;
return ServletContextResponse.getServletContextResponse(_response);
}

@Override
Expand Down Expand Up @@ -953,6 +959,8 @@ public boolean isWriting()
@Override
public void write(boolean last, ByteBuffer byteBuffer, Callback callback)
{
if (_included)
last = false;
try
{
if (BufferUtil.hasContent(byteBuffer))
Expand Down Expand Up @@ -1002,6 +1010,8 @@ public void setStatus(int code)
{
if (LOG.isDebugEnabled())
LOG.debug("{}.setStatus({})", this.getClass().getSimpleName(), code);
if (_included)
return;
_response.setStatus(code);
}

Expand Down Expand Up @@ -1033,6 +1043,12 @@ public CompletableFuture<Void> writeInterim(int status, HttpFields headers)
{
return null;
}

@Override
public String toString()
{
return "%s@%x{%s,%s}".formatted(this.getClass().getSimpleName(), hashCode(), this._coreRequest, _response);
}
}

private class ServletResourceService extends ResourceService implements ResourceService.WelcomeFactory
Expand All @@ -1045,23 +1061,14 @@ private ServletResourceService(ServletContextHandler servletContextHandler)
}

@Override
public String getWelcomeTarget(Request coreRequest)
public String getWelcomeTarget(HttpContent content, Request coreRequest)
{
String[] welcomes = _servletContextHandler.getWelcomeFiles();
if (welcomes == null)
return null;

HttpServletRequest request = getServletRequest(coreRequest);
String pathInContext = Request.getPathInContext(coreRequest);
String includedServletPath = (String)request.getAttribute(RequestDispatcher.INCLUDE_SERVLET_PATH);
String requestTarget;
if (includedServletPath != null)
requestTarget = getIncludedPathInContext(request, includedServletPath, isPathInfoOnly());
else
requestTarget = isPathInfoOnly() ? request.getPathInfo() : pathInContext;

String welcomeTarget = null;
Resource base = _baseResource.resolve(requestTarget);
Resource base = content.getResource();
if (Resources.isReadableDirectory(base))
{
for (String welcome : welcomes)
Expand All @@ -1070,13 +1077,16 @@ public String getWelcomeTarget(Request coreRequest)

// If the welcome resource is a file, it has
// precedence over resources served by Servlets.
Resource welcomePath = base.resolve(welcome);
Resource welcomePath = content.getResource().resolve(welcome);
if (Resources.isReadableFile(welcomePath))
return welcomeInContext;

// Check whether a Servlet may serve the welcome resource.
if (_welcomeServletMode != WelcomeServletMode.NONE && welcomeTarget == null)
{
if (isPathInfoOnly() && !isIncluded(getServletRequest(coreRequest)))
welcomeTarget = URIUtil.addPaths(getServletRequest(coreRequest).getPathInfo(), welcome);

ServletHandler.MappedServlet entry = _servletContextHandler.getServletHandler().getMappedServlet(welcomeInContext);
// Is there a different Servlet that may serve the welcome resource?
if (entry != null && entry.getServletHolder().getServletInstance() != DefaultServlet.this)
Expand Down Expand Up @@ -1186,7 +1196,8 @@ protected void writeHttpError(Request coreRequest, Response coreResponse, Callba
HttpServletResponse response = getServletResponse(coreResponse);
try
{
// TODO: not sure if this is allowed here.
if (isIncluded(request))
return;
if (cause != null)
request.setAttribute(RequestDispatcher.ERROR_EXCEPTION, cause);
response.sendError(statusCode, reason);
Expand Down Expand Up @@ -1266,13 +1277,20 @@ private static class ForcedCharacterEncodingHttpContent extends HttpContent.Wrap

public ForcedCharacterEncodingHttpContent(HttpContent content, String characterEncoding)
{
super(content);
super(Objects.requireNonNull(content));
this.characterEncoding = characterEncoding;
String mimeType = content.getContentTypeValue();
int idx = mimeType.indexOf(";charset");
if (idx >= 0)
mimeType = mimeType.substring(0, idx);
this.contentType = mimeType + ";charset=" + this.characterEncoding;
if (content.getContentTypeValue() == null || content.getResource().isDirectory())
{
this.contentType = null;
}
else
{
String mimeType = content.getContentTypeValue();
int idx = mimeType.indexOf(";charset");
if (idx >= 0)
mimeType = mimeType.substring(0, idx);
this.contentType = mimeType + ";charset=" + characterEncoding;
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ public class EmbeddedJettyHttp2Test {

@BeforeEach
public void resetState() {
decoder = new HpackDecoder(4096, 8192);
decoder = new HpackDecoder(8192);
decoder.setMaxTableCapacity(4096);
responses = new HashMap<>();
}

Expand Down Expand Up @@ -253,7 +254,6 @@ public void http2NioExchange() throws Exception {
final CountDownLatch latch = new CountDownLatch(3);

ServletContextHandler handler = new ServletContextHandler("/");
handler.setAllowNullPathInfo(true);
handler.setAllowNullPathInContext(true);
handler.addServlet(new ServletHolder("default-servlet", new HttpServlet() {
@Override
Expand Down Expand Up @@ -468,7 +468,6 @@ public void http2NioExchangeWithDirectUpgrade() throws Exception {
final CountDownLatch latch = new CountDownLatch(3);

ServletContextHandler handler = new ServletContextHandler("/");
handler.setAllowNullPathInfo(true);
handler.setAllowNullPathInContext(true);
handler.addServlet(new ServletHolder("default-servlet", new HttpServlet() {
@Override
Expand Down
Loading

0 comments on commit 9c505ac

Please sign in to comment.