Issue #5057 - Included root context path (#5058)

* Fixes #5057 Included root context path

Root context path in include should be empty string.

* Issue #5057

merged context path methods as result of review.
ServletContent.getContextPath now returns the encoded contextPath (if anybody is silly enough to have one).
This commit is contained in:
Greg Wilkins 2020-07-20 17:35:48 +02:00 committed by GitHub
parent 89045959ac
commit 65de149f84
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 109 additions and 10 deletions

View File

@ -109,7 +109,7 @@ public class Dispatcher implements RequestDispatcher
IncludeAttributes attr = new IncludeAttributes(old_attr);
attr._requestURI = _uri.getPath();
attr._contextPath = _contextHandler.getContextPath();
attr._contextPath = _contextHandler.getRequestContextPath();
attr._servletPath = null; // set by ServletHandler
attr._pathInfo = _pathInContext;
attr._query = _uri.getQuery();

View File

@ -528,7 +528,7 @@ public class Server extends HandlerWrapper implements Attributes
// this is a dispatch with a path
ServletContext context = event.getServletContext();
String query = baseRequest.getQueryString();
baseRequest.setURIPathQuery(URIUtil.addEncodedPaths(context == null ? null : URIUtil.encodePath(context.getContextPath()), path));
baseRequest.setURIPathQuery(URIUtil.addEncodedPaths(context == null ? null : context.getContextPath(), path));
HttpURI uri = baseRequest.getHttpURI();
baseRequest.setPathInfo(uri.getDecodedPath());
if (uri.getQuery() != null)

View File

@ -591,6 +591,17 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
return _contextPathEncoded;
}
/**
* Get the context path in a form suitable to be returned from {@link HttpServletRequest#getContextPath()}
* or {@link ServletContext#getContextPath()}.
* @return Returns the encoded contextPath, or empty string for root context
*/
public String getRequestContextPath()
{
String contextPathEncoded = getContextPathEncoded();
return "/".equals(contextPathEncoded) ? "" : contextPathEncoded;
}
/*
* @see javax.servlet.ServletContext#getInitParameter(java.lang.String)
*/
@ -1267,10 +1278,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
__context.set(_scontext);
if (!DispatcherType.INCLUDE.equals(dispatch) && target.startsWith("/"))
{
if (_contextPath.length() == 1)
baseRequest.setContextPath("");
else
baseRequest.setContextPath(getContextPathEncoded());
baseRequest.setContextPath(getRequestContextPath());
baseRequest.setServletPath(null);
baseRequest.setPathInfo(pathInfo);
}
@ -2418,10 +2426,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
@Override
public String getContextPath()
{
if ((_contextPath != null) && _contextPath.equals(URIUtil.SLASH))
return "";
return _contextPath;
return getRequestContextPath();
}
@Override

View File

@ -18,6 +18,7 @@
package org.eclipse.jetty.servlet;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@ -25,8 +26,12 @@ import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.HttpURLConnection;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.DispatcherType;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@ -34,6 +39,7 @@ import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.toolchain.test.IO;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@ -71,6 +77,45 @@ public class IncludedServletTest
}
}
public static class IncludedAttrServlet extends HttpServlet
{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
if (req.getDispatcherType() == DispatcherType.INCLUDE)
{
if (req.getAttribute("included") == null)
{
req.setAttribute("included", Boolean.TRUE);
dumpAttrs("BEFORE1", req, resp.getOutputStream());
req.getRequestDispatcher("two").include(req, resp);
dumpAttrs("AFTER1", req, resp.getOutputStream());
}
else
{
dumpAttrs("DURING", req, resp.getOutputStream());
}
}
else
{
resp.setContentType("text/plain");
dumpAttrs("BEFORE0", req, resp.getOutputStream());
req.getRequestDispatcher("one").include(req, resp);
dumpAttrs("AFTER0", req, resp.getOutputStream());
}
}
private void dumpAttrs(String tag, HttpServletRequest req, ServletOutputStream out) throws IOException
{
out.println(String.format("%s: %s='%s'", tag, RequestDispatcher.INCLUDE_CONTEXT_PATH,
req.getAttribute(RequestDispatcher.INCLUDE_CONTEXT_PATH)));
out.println(String.format("%s: %s='%s'", tag, RequestDispatcher.INCLUDE_SERVLET_PATH,
req.getAttribute(RequestDispatcher.INCLUDE_SERVLET_PATH)));
out.println(String.format("%s: %s='%s'", tag, RequestDispatcher.INCLUDE_PATH_INFO,
req.getAttribute(RequestDispatcher.INCLUDE_PATH_INFO)));
}
}
private Server server;
private URI baseUri;
@ -87,6 +132,7 @@ public class IncludedServletTest
context.setContextPath("/");
context.addServlet(TopServlet.class, "/top");
context.addServlet(IncludedServlet.class, "/included");
context.addServlet(IncludedAttrServlet.class, "/attr/*");
server.setHandler(context);
@ -173,4 +219,52 @@ public class IncludedServletTest
IO.close(in);
}
}
@Test
public void testIncludeAttributes() throws IOException
{
URI uri = baseUri.resolve("/attr/one");
InputStream in = null;
BufferedReader reader = null;
HttpURLConnection connection = null;
try
{
connection = (HttpURLConnection)uri.toURL().openConnection();
connection.connect();
assertThat(connection.getResponseCode(), is(HttpURLConnection.HTTP_OK));
in = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(in));
List<String> result = new ArrayList<>();
String line = reader.readLine();
while (line != null)
{
result.add(line);
line = reader.readLine();
}
assertThat(result, Matchers.contains(
"BEFORE0: javax.servlet.include.context_path='null'",
"BEFORE0: javax.servlet.include.servlet_path='null'",
"BEFORE0: javax.servlet.include.path_info='null'",
"BEFORE1: javax.servlet.include.context_path=''",
"BEFORE1: javax.servlet.include.servlet_path='/attr'",
"BEFORE1: javax.servlet.include.path_info='/one'",
"DURING: javax.servlet.include.context_path=''",
"DURING: javax.servlet.include.servlet_path='/attr'",
"DURING: javax.servlet.include.path_info='/two'",
"AFTER1: javax.servlet.include.context_path=''",
"AFTER1: javax.servlet.include.servlet_path='/attr'",
"AFTER1: javax.servlet.include.path_info='/one'",
"AFTER0: javax.servlet.include.context_path='null'",
"AFTER0: javax.servlet.include.servlet_path='null'",
"AFTER0: javax.servlet.include.path_info='null'"
));
}
finally
{
IO.close(reader);
IO.close(in);
}
}
}