Fixes #5779 Include should not set pathInContext (#5780)

Fixes #5779 by ensuring that ContextHandler does not set pathInContext for include.
This commit is contained in:
Greg Wilkins 2020-12-11 10:04:31 +01:00 committed by GitHub
parent 37c040ebab
commit f17a5fb3fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 98 additions and 7 deletions

View File

@ -1225,7 +1225,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
final Thread currentThread = Thread.currentThread();
final ClassLoader oldClassloader = currentThread.getContextClassLoader();
Context oldContext;
String oldPathInContext = null;
String oldPathInContext = baseRequest.getPathInContext();;
String pathInContext = target;
DispatcherType dispatch = baseRequest.getDispatcherType();
@ -1267,14 +1267,15 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
try
{
oldPathInContext = baseRequest.getPathInContext();
// Update the paths
baseRequest.setContext(_scontext, pathInContext);
__context.set(_scontext);
baseRequest.setContext(_scontext,
(DispatcherType.INCLUDE.equals(dispatch) || !target.startsWith("/")) ? oldPathInContext : pathInContext);
if (oldContext != _scontext)
{
__context.set(_scontext);
enterScope(baseRequest, dispatch);
}
if (LOG.isDebugEnabled())
LOG.debug("context={}|{}|{} @ {}", baseRequest.getContextPath(), baseRequest.getServletPath(), baseRequest.getPathInfo(), this);
@ -1291,10 +1292,12 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
if (_classLoader != null)
currentThread.setContextClassLoader(oldClassloader);
// reset the context and servlet path.
baseRequest.setContext(oldContext, oldPathInContext);
// reset the context
__context.set(oldContext);
}
// reset pathInContext
baseRequest.setContext(oldContext, oldPathInContext);
}
}

View File

@ -259,6 +259,44 @@ public class DispatcherTest
assertEquals(expected, responses);
}
@Test
public void testForwardExForwardEx() throws Exception
{
_contextHandler.addServlet(RelativeDispatch2Servlet.class, "/RelDispatchServlet/*");
_contextHandler.addServlet(ThrowServlet.class, "/include/throw/*");
String expected =
"HTTP/1.1 200 OK\r\n" +
"Content-Length: 56\r\n" +
"\r\n" +
"THROWING\r\n" +
"CAUGHT2 java.io.IOException: Expected\r\n" +
"AFTER\r\n";
String responses = _connector.getResponse("GET /context/RelDispatchServlet?path=include/throw HTTP/1.0\n\n");
assertEquals(expected, responses);
}
@Test
public void testIncludeExIncludeEx() throws Exception
{
_contextHandler.addServlet(RelativeDispatch2Servlet.class, "/RelDispatchServlet/*");
_contextHandler.addServlet(ThrowServlet.class, "/include/throw/*");
String expected =
"HTTP/1.1 200 OK\r\n" +
"Content-Length: 122\r\n" +
"\r\n" +
"BEFORE\r\n" +
"THROWING\r\n" +
"CAUGHT1 java.io.IOException: Expected\r\n" +
"BETWEEN\r\n" +
"THROWING\r\n" +
"CAUGHT2 java.io.IOException: Expected\r\n" +
"AFTER\r\n";
String responses = _connector.getResponse("GET /context/RelDispatchServlet?include=true&path=include/throw HTTP/1.0\n\n");
assertEquals(expected, responses);
}
@Test
public void testForwardThenInclude() throws Exception
{
@ -670,6 +708,46 @@ public class DispatcherTest
}
}
public static class RelativeDispatch2Servlet extends HttpServlet implements Servlet
{
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
RequestDispatcher dispatcher = null;
String path = request.getParameter("path");
String include = request.getParameter("include");
ServletOutputStream out = response.getOutputStream();
try
{
out.println("BEFORE");
if (Boolean.parseBoolean(include))
request.getRequestDispatcher(path).include(request, response);
else
request.getRequestDispatcher(path).forward(request, response);
out.println("AFTER1");
}
catch (Throwable t)
{
out.println("CAUGHT1 " + t);
}
try
{
out.println("BETWEEN");
if (Boolean.parseBoolean(include))
request.getRequestDispatcher(path).include(request, response);
else
request.getRequestDispatcher(path).forward(request, response);
out.println("AFTER2");
}
catch (Throwable t)
{
out.println("CAUGHT2 " + t);
}
out.println("AFTER");
}
}
public static class RogerThatServlet extends GenericServlet
{
@Override
@ -679,6 +757,16 @@ public class DispatcherTest
}
}
public static class ThrowServlet extends GenericServlet
{
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException
{
res.getOutputStream().println("THROWING");
throw new IOException("Expected");
}
}
public static class EchoServlet extends GenericServlet
{
@Override