Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix ee10 path info only (alternative) #9934

Merged
merged 6 commits into from
Jun 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -440,11 +440,12 @@ private String matchesEtag(String contentETag, String requestEtag)

protected void sendWelcome(HttpContent content, String pathInContext, boolean endsWithSlash, Request request, Response response, Callback callback) throws Exception
{
if (!Objects.requireNonNull(content).getResource().isDirectory())
throw new IllegalArgumentException("content must be a directory");

if (LOG.isDebugEnabled())
{
LOG.debug("sendWelcome(content={}, pathInContext={}, endsWithSlash={}, req={}, resp={}, callback={})",
content, pathInContext, endsWithSlash, request, response, callback);
}

// Redirect to directory
if (!endsWithSlash)
Expand All @@ -460,7 +461,7 @@ protected void sendWelcome(HttpContent content, String pathInContext, boolean en
}

// process optional Welcome behaviors
if (welcome(request, response, callback))
if (welcome(content, request, response, callback))
return;

if (!passConditionalHeaders(request, response, content, callback))
Expand Down Expand Up @@ -499,9 +500,9 @@ public record WelcomeAction(String target, WelcomeMode mode)
{
}

private boolean welcome(Request request, Response response, Callback callback) throws Exception
private boolean welcome(HttpContent content, Request request, Response response, Callback callback) throws Exception
{
WelcomeAction welcomeAction = processWelcome(request);
WelcomeAction welcomeAction = processWelcome(content, request);
if (LOG.isDebugEnabled())
LOG.debug("welcome(req={}, rsp={}, cbk={}) welcomeAction={}", request, response, callback, welcomeAction);

Expand Down Expand Up @@ -581,9 +582,9 @@ protected void rehandleWelcome(Request request, Response response, Callback call
Response.writeError(request, response, callback, HttpStatus.INTERNAL_SERVER_ERROR_500);
}

private WelcomeAction processWelcome(Request request) throws IOException
private WelcomeAction processWelcome(HttpContent content, Request request) throws IOException
{
String welcomeTarget = getWelcomeFactory().getWelcomeTarget(request);
String welcomeTarget = getWelcomeFactory().getWelcomeTarget(content, request);
if (welcomeTarget == null)
return null;

Expand Down Expand Up @@ -892,7 +893,7 @@ public interface WelcomeFactory
* @return The URI path of the matching welcome target in context or null
* if no welcome target was found
*/
String getWelcomeTarget(Request request) throws IOException;
String getWelcomeTarget(HttpContent content, Request request) throws IOException;
}

private static class ContentWriterIteratingCallback extends IteratingCallback
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ protected HttpContent.Factory newHttpContentFactory()

protected ResourceService.WelcomeFactory setupWelcomeFactory()
{
return request ->
return (content, request) ->
{
if (_welcomes == null)
return null;
Expand All @@ -131,7 +131,7 @@ protected ResourceService.WelcomeFactory setupWelcomeFactory()
{
String pathInContext = Request.getPathInContext(request);
String welcomeInContext = URIUtil.addPaths(pathInContext, welcome);
Resource welcomePath = _baseResource.resolve(pathInContext).resolve(welcome);
Resource welcomePath = content.getResource().resolve(welcome);
if (Resources.isReadableFile(welcomePath))
return welcomeInContext;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1015,23 +1015,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();
lorban marked this conversation as resolved.
Show resolved Hide resolved
if (Resources.isReadableDirectory(base))
lorban marked this conversation as resolved.
Show resolved Hide resolved
{
for (String welcome : welcomes)
Expand All @@ -1040,13 +1031,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
Original file line number Diff line number Diff line change
Expand Up @@ -3185,6 +3185,63 @@ public void destroy()
}
}

@Test
public void testPathInfoOnly() throws Exception
{
ServletContextHandler context = new ServletContextHandler(null, "/c1", ServletContextHandler.NO_SESSIONS);
context.setWelcomeFiles(new String[]{"index.y", "index.x"});
ServletHolder indexServlet = new ServletHolder("index-servlet", new HttpServlet()
{
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
resp.setContentType("text/plain");
resp.setCharacterEncoding("UTF-8");
resp.getWriter().println(req.getRequestURI());
resp.getWriter().println("testPathInfoOnly-OK");
resp.getWriter().close();
}
});

ServletMapping indexMapping = new ServletMapping();
indexMapping.setServletName("index-servlet");
indexMapping.setPathSpecs(new String[]{"*.x", "*.y"});
context.getServletHandler().addServlet(indexServlet);
context.getServletHandler().addServletMapping(indexMapping);

Path pathTest = MavenTestingUtils.getTestResourcePath("pathTest");

Path defaultDir = pathTest.resolve("default");
ServletHolder slashHolder = new ServletHolder("default", new DefaultServlet());
slashHolder.setInitParameter("redirectWelcome", "false");
slashHolder.setInitParameter("welcomeServlets", "true");
slashHolder.setInitParameter("pathInfoOnly", "false");
slashHolder.setInitParameter("baseResource", defaultDir.toAbsolutePath().toString());
context.addServlet(slashHolder, "/");

Path rDir = pathTest.resolve("rdir");
ServletHolder rHolder = new ServletHolder("rdefault", new DefaultServlet());
rHolder.setInitParameter("redirectWelcome", "false");
rHolder.setInitParameter("welcomeServlets", "true");
rHolder.setInitParameter("pathInfoOnly", "true");
rHolder.setInitParameter("baseResource", rDir.toAbsolutePath().toString());
context.addServlet(rHolder, "/r/*");

server.stop();
server.setHandler(context);
server.start();
String rawRequest = """
GET /c1/r/ HTTP/1.1\r
Host: localhost\r
Connection: close\r
\r
""";

String rawResponse = connector.getResponse(rawRequest);
HttpTester.Response response = HttpTester.parseResponse(rawResponse);
assertThat(response.getContent(), containsString("testPathInfoOnly-OK"));
}

public static class WriterFilter implements Filter
{
@Override
Expand Down
Empty file.
Empty file.