* Issue #4741 - fixes to jetty implementation of HttpServletMapping Signed-off-by: Lachlan Roberts <lachlan@webtide.com> * Issue #4741 - don't lazily generate HttpServletMapping to preserve servletName Signed-off-by: Lachlan Roberts <lachlan@webtide.com> * Issue #4741 - tests should expect no leading / for matchValue Signed-off-by: Lachlan Roberts <lachlan@webtide.com> * resolving TODOs from review - removed pathSpec from Request - getServletMapping moved to ServletHandler Signed-off-by: Lachlan Roberts <lachlan@webtide.com> * Issue #4741 - only create HttpServletMapping for exact matches once Signed-off-by: Lachlan Roberts <lachlan@webtide.com> * use wrapped attributes for async dispatch Signed-off-by: Lachlan Roberts <lachlan@webtide.com> * Issue #4741 - Changes from review, revert async attribute wrapping Signed-off-by: Lachlan Roberts <lachlan@webtide.com> * Issue #4741 - Changes from review Signed-off-by: Lachlan Roberts <lachlan@webtide.com> * Issue #4741 Async ServletMapping Greatly increased the scope of this PR by combining the servletPath and pathInfo into the ServletPathMapping class that implements the HttpServletPathMapping interface. This allows us to greatly simplify the matching of servlets and reduce the number of times we need to actually to the match per request. Signed-off-by: Greg Wilkins <gregw@webtide.com> * Issue #4741 Async ServletMapping Fixed problems with previous commit more cleanup of attributes in dispatcher. Signed-off-by: Greg Wilkins <gregw@webtide.com> * Issue #4741 Async ServletMapping More code cleanups Signed-off-by: Greg Wilkins <gregw@webtide.com> * Issue #4741 Async ServletMapping Named dispatch cleanup Signed-off-by: Greg Wilkins <gregw@webtide.com> * Issue #4741 Async ServletMapping misc cleanup Signed-off-by: Greg Wilkins <gregw@webtide.com> * Issue #4741 Async HttpServletMapping Added tests for named dispatchers Do not use ServletPathMapping for named dispatch Signed-off-by: Greg Wilkins <gregw@webtide.com> * Issue #4741 Async HttpServletMapping renamed confusing isDefault method on ServletMapping Signed-off-by: Greg Wilkins <gregw@webtide.com> * Issue #4741 Async HttpServletMapping simplified setAttribute Signed-off-by: Greg Wilkins <gregw@webtide.com> * Issue #4741 Async HttpServletMapping added javadoc about AsyncAttributes Signed-off-by: Greg Wilkins <gregw@webtide.com> * Issue #4741 Async HttpServletMapping Fixed javadoc Signed-off-by: Greg Wilkins <gregw@webtide.com> Co-authored-by: Greg Wilkins <gregw@webtide.com>
This commit is contained in:
parent
598accfd3a
commit
8d5430bc60
|
@ -211,7 +211,7 @@ public class WebServletAnnotation extends DiscoveredAnnotation
|
|||
for (String p : urlPatternList)
|
||||
{
|
||||
ServletMapping existingMapping = _context.getServletHandler().getServletMapping(p);
|
||||
if (existingMapping != null && existingMapping.isDefault())
|
||||
if (existingMapping != null && existingMapping.isFromDefaultDescriptor())
|
||||
{
|
||||
String[] updatedPaths = ArrayUtil.removeFromArray(existingMapping.getPathSpecs(), p);
|
||||
//if we removed the last path from a servletmapping, delete the servletmapping
|
||||
|
@ -264,7 +264,7 @@ public class WebServletAnnotation extends DiscoveredAnnotation
|
|||
return false;
|
||||
for (ServletMapping m : mappings)
|
||||
{
|
||||
if (!m.isDefault())
|
||||
if (!m.isFromDefaultDescriptor())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -117,7 +117,7 @@ public class TestServletAnnotations
|
|||
ServletMapping m = new ServletMapping();
|
||||
m.setPathSpec("/");
|
||||
m.setServletName("default");
|
||||
m.setDefault(true); //this mapping will be from a default descriptor
|
||||
m.setFromDefaultDescriptor(true); //this mapping will be from a default descriptor
|
||||
wac.getServletHandler().addServletMapping(m);
|
||||
|
||||
WebServletAnnotation annotation = new WebServletAnnotation(wac, "org.eclipse.jetty.annotations.ServletD", null);
|
||||
|
@ -150,13 +150,13 @@ public class TestServletAnnotations
|
|||
ServletMapping m = new ServletMapping();
|
||||
m.setPathSpec("/");
|
||||
m.setServletName("default");
|
||||
m.setDefault(true); //this mapping will be from a default descriptor
|
||||
m.setFromDefaultDescriptor(true); //this mapping will be from a default descriptor
|
||||
wac.getServletHandler().addServletMapping(m);
|
||||
|
||||
ServletMapping m2 = new ServletMapping();
|
||||
m2.setPathSpec("/other");
|
||||
m2.setServletName("default");
|
||||
m2.setDefault(true); //this mapping will be from a default descriptor
|
||||
m2.setFromDefaultDescriptor(true); //this mapping will be from a default descriptor
|
||||
wac.getServletHandler().addServletMapping(m2);
|
||||
|
||||
WebServletAnnotation annotation = new WebServletAnnotation(wac, "org.eclipse.jetty.annotations.ServletD", null);
|
||||
|
@ -235,7 +235,7 @@ public class TestServletAnnotations
|
|||
|
||||
ServletMapping m = new ServletMapping();
|
||||
m.setPathSpec("/default");
|
||||
m.setDefault(true);
|
||||
m.setFromDefaultDescriptor(true);
|
||||
m.setServletName("DServlet");
|
||||
wac.getServletHandler().addServletMapping(m);
|
||||
|
||||
|
|
|
@ -106,7 +106,7 @@ public class QuickStartDescriptorProcessor extends IterativeDescriptorProcessor
|
|||
{
|
||||
String origin = node.getAttribute(_originAttributeName);
|
||||
if (!StringUtil.isBlank(origin) && origin.startsWith(DefaultsDescriptor.class.getSimpleName()))
|
||||
mapping.setDefault(true);
|
||||
mapping.setFromDefaultDescriptor(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@ public class TestQuickStart
|
|||
server.dumpStdErr();
|
||||
|
||||
//verify that FooServlet is now mapped to / and not the DefaultServlet
|
||||
ServletHolder sh = webapp.getServletHandler().getMappedServlet("/").getResource();
|
||||
ServletHolder sh = webapp.getServletHandler().getMappedServlet("/").getServletHolder();
|
||||
assertNotNull(sh);
|
||||
assertEquals("foo", sh.getName());
|
||||
}
|
||||
|
|
|
@ -21,30 +21,25 @@ package org.eclipse.jetty.server;
|
|||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import javax.servlet.AsyncContext;
|
||||
import javax.servlet.http.HttpServletMapping;
|
||||
|
||||
import org.eclipse.jetty.util.Attributes;
|
||||
|
||||
class AsyncAttributes extends Attributes.Wrapper
|
||||
{
|
||||
private String _requestURI;
|
||||
private String _contextPath;
|
||||
private String _servletPath;
|
||||
private String _pathInfo;
|
||||
private String _queryString;
|
||||
private HttpServletMapping _httpServletMapping;
|
||||
private final String _requestURI;
|
||||
private final String _contextPath;
|
||||
private final String _pathInContext;
|
||||
private ServletPathMapping _mapping;
|
||||
private final String _queryString;
|
||||
|
||||
public AsyncAttributes(Attributes attributes, String requestUri, String contextPath, String servletPath, String pathInfo, String queryString, HttpServletMapping httpServletMapping)
|
||||
public AsyncAttributes(Attributes attributes, String requestUri, String contextPath, String pathInContext, ServletPathMapping mapping, String queryString)
|
||||
{
|
||||
super(attributes);
|
||||
|
||||
// TODO: make fields final in jetty-10 and NOOP when one of these attributes is set.
|
||||
_requestURI = requestUri;
|
||||
_contextPath = contextPath;
|
||||
_servletPath = servletPath;
|
||||
_pathInfo = pathInfo;
|
||||
_pathInContext = pathInContext;
|
||||
_mapping = mapping;
|
||||
_queryString = queryString;
|
||||
_httpServletMapping = httpServletMapping;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -57,13 +52,13 @@ class AsyncAttributes extends Attributes.Wrapper
|
|||
case AsyncContext.ASYNC_CONTEXT_PATH:
|
||||
return _contextPath;
|
||||
case AsyncContext.ASYNC_SERVLET_PATH:
|
||||
return _servletPath;
|
||||
return _mapping == null ? null : _mapping.getServletPath();
|
||||
case AsyncContext.ASYNC_PATH_INFO:
|
||||
return _pathInfo;
|
||||
return _mapping == null ? _pathInContext : _mapping.getPathInfo();
|
||||
case AsyncContext.ASYNC_QUERY_STRING:
|
||||
return _queryString;
|
||||
case AsyncContext.ASYNC_MAPPING:
|
||||
return _httpServletMapping;
|
||||
return _mapping;
|
||||
default:
|
||||
return super.getAttribute(key);
|
||||
}
|
||||
|
@ -73,18 +68,12 @@ class AsyncAttributes extends Attributes.Wrapper
|
|||
public Set<String> getAttributeNameSet()
|
||||
{
|
||||
Set<String> set = new HashSet<>(super.getAttributeNameSet());
|
||||
if (_requestURI != null)
|
||||
set.add(AsyncContext.ASYNC_REQUEST_URI);
|
||||
if (_contextPath != null)
|
||||
set.add(AsyncContext.ASYNC_CONTEXT_PATH);
|
||||
if (_servletPath != null)
|
||||
set.add(AsyncContext.ASYNC_SERVLET_PATH);
|
||||
if (_pathInfo != null)
|
||||
set.add(AsyncContext.ASYNC_PATH_INFO);
|
||||
if (_queryString != null)
|
||||
set.add(AsyncContext.ASYNC_QUERY_STRING);
|
||||
if (_httpServletMapping != null)
|
||||
set.add(AsyncContext.ASYNC_MAPPING);
|
||||
set.add(AsyncContext.ASYNC_REQUEST_URI);
|
||||
set.add(AsyncContext.ASYNC_CONTEXT_PATH);
|
||||
set.add(AsyncContext.ASYNC_SERVLET_PATH);
|
||||
set.add(AsyncContext.ASYNC_PATH_INFO);
|
||||
set.add(AsyncContext.ASYNC_QUERY_STRING);
|
||||
set.add(AsyncContext.ASYNC_MAPPING);
|
||||
return set;
|
||||
}
|
||||
|
||||
|
@ -94,54 +83,17 @@ class AsyncAttributes extends Attributes.Wrapper
|
|||
switch (key)
|
||||
{
|
||||
case AsyncContext.ASYNC_REQUEST_URI:
|
||||
_requestURI = (String)value;
|
||||
break;
|
||||
case AsyncContext.ASYNC_CONTEXT_PATH:
|
||||
_contextPath = (String)value;
|
||||
break;
|
||||
case AsyncContext.ASYNC_SERVLET_PATH:
|
||||
_servletPath = (String)value;
|
||||
break;
|
||||
case AsyncContext.ASYNC_PATH_INFO:
|
||||
_pathInfo = (String)value;
|
||||
break;
|
||||
case AsyncContext.ASYNC_QUERY_STRING:
|
||||
_queryString = (String)value;
|
||||
break;
|
||||
case AsyncContext.ASYNC_MAPPING:
|
||||
_httpServletMapping = (HttpServletMapping)value;
|
||||
// Ignore sets for these reserved names as this class is applied
|
||||
// we will always override these particular attributes.
|
||||
break;
|
||||
default:
|
||||
super.setAttribute(key, value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearAttributes()
|
||||
{
|
||||
_requestURI = null;
|
||||
_contextPath = null;
|
||||
_servletPath = null;
|
||||
_pathInfo = null;
|
||||
_queryString = null;
|
||||
_httpServletMapping = null;
|
||||
super.clearAttributes();
|
||||
}
|
||||
|
||||
public static void applyAsyncAttributes(Attributes attributes, String requestURI, String contextPath, String servletPath, String pathInfo, String queryString, HttpServletMapping httpServletMapping)
|
||||
{
|
||||
if (requestURI != null)
|
||||
attributes.setAttribute(AsyncContext.ASYNC_REQUEST_URI, requestURI);
|
||||
if (contextPath != null)
|
||||
attributes.setAttribute(AsyncContext.ASYNC_CONTEXT_PATH, contextPath);
|
||||
if (servletPath != null)
|
||||
attributes.setAttribute(AsyncContext.ASYNC_SERVLET_PATH, servletPath);
|
||||
if (pathInfo != null)
|
||||
attributes.setAttribute(AsyncContext.ASYNC_PATH_INFO, pathInfo);
|
||||
if (queryString != null)
|
||||
attributes.setAttribute(AsyncContext.ASYNC_QUERY_STRING, queryString);
|
||||
if (httpServletMapping != null)
|
||||
attributes.setAttribute(AsyncContext.ASYNC_MAPPING, httpServletMapping);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,6 @@ import javax.servlet.RequestDispatcher;
|
|||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletMapping;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
|
@ -101,14 +100,7 @@ public class Dispatcher implements RequestDispatcher
|
|||
}
|
||||
else
|
||||
{
|
||||
IncludeAttributes attr = new IncludeAttributes(old_attr);
|
||||
|
||||
attr._requestURI = _uri.getPath();
|
||||
attr._contextPath = _contextHandler.getContextPath();
|
||||
attr._servletPath = null; // set by ServletHandler
|
||||
attr._pathInfo = _pathInContext;
|
||||
attr._query = _uri.getQuery();
|
||||
attr._mapping = null; //set by ServletHandler
|
||||
IncludeAttributes attr = new IncludeAttributes(old_attr, _uri.getPath(), _contextHandler.getContextPath(), _pathInContext, _uri.getQuery());
|
||||
if (attr._query != null)
|
||||
baseRequest.mergeQueryParameters(baseRequest.getQueryString(), attr._query);
|
||||
baseRequest.setAttributes(attr);
|
||||
|
@ -147,7 +139,7 @@ public class Dispatcher implements RequestDispatcher
|
|||
final String old_context_path = baseRequest.getContextPath();
|
||||
final String old_servlet_path = baseRequest.getServletPath();
|
||||
final String old_path_info = baseRequest.getPathInfo();
|
||||
final HttpServletMapping old_mapping = baseRequest.getHttpServletMapping();
|
||||
final ServletPathMapping old_mapping = baseRequest.getServletPathMapping();
|
||||
|
||||
final MultiMap<String> old_query_params = baseRequest.getQueryParameters();
|
||||
final Attributes old_attr = baseRequest.getAttributes();
|
||||
|
@ -163,30 +155,26 @@ public class Dispatcher implements RequestDispatcher
|
|||
}
|
||||
else
|
||||
{
|
||||
ForwardAttributes attr = new ForwardAttributes(old_attr);
|
||||
|
||||
//If we have already been forwarded previously, then keep using the established
|
||||
//original value. Otherwise, this is the first forward and we need to establish the values.
|
||||
//Note: the established value on the original request for pathInfo and
|
||||
//for queryString is allowed to be null, but cannot be null for the other values.
|
||||
if (old_attr.getAttribute(FORWARD_REQUEST_URI) != null)
|
||||
{
|
||||
attr._pathInfo = (String)old_attr.getAttribute(FORWARD_PATH_INFO);
|
||||
attr._query = (String)old_attr.getAttribute(FORWARD_QUERY_STRING);
|
||||
attr._requestURI = (String)old_attr.getAttribute(FORWARD_REQUEST_URI);
|
||||
attr._contextPath = (String)old_attr.getAttribute(FORWARD_CONTEXT_PATH);
|
||||
attr._servletPath = (String)old_attr.getAttribute(FORWARD_SERVLET_PATH);
|
||||
attr._mapping = (HttpServletMapping)old_attr.getAttribute(FORWARD_MAPPING);
|
||||
}
|
||||
else
|
||||
{
|
||||
attr._pathInfo = old_path_info;
|
||||
attr._query = old_uri.getQuery();
|
||||
attr._requestURI = old_uri.getPath();
|
||||
attr._contextPath = old_context_path;
|
||||
attr._servletPath = old_servlet_path;
|
||||
attr._mapping = old_mapping;
|
||||
}
|
||||
// If we have already been forwarded previously, then keep using the established
|
||||
// original value. Otherwise, this is the first forward and we need to establish the values.
|
||||
// Note: the established value on the original request for pathInfo and
|
||||
// for queryString is allowed to be null, but cannot be null for the other values.
|
||||
// Note: the pathInfo is passed as the pathInContext since it is only used when there is
|
||||
// no mapping, and when there is no mapping the pathInfo is the pathInContext.
|
||||
// TODO Ultimately it is intended for the request to carry the pathInContext for easy access
|
||||
ForwardAttributes attr = old_attr.getAttribute(FORWARD_REQUEST_URI) != null
|
||||
? new ForwardAttributes(old_attr,
|
||||
(String)old_attr.getAttribute(FORWARD_REQUEST_URI),
|
||||
(String)old_attr.getAttribute(FORWARD_CONTEXT_PATH),
|
||||
(String)old_attr.getAttribute(FORWARD_PATH_INFO),
|
||||
(ServletPathMapping)old_attr.getAttribute(FORWARD_MAPPING),
|
||||
(String)old_attr.getAttribute(FORWARD_QUERY_STRING))
|
||||
: new ForwardAttributes(old_attr,
|
||||
old_uri.getPath(),
|
||||
old_context_path,
|
||||
baseRequest.getPathInfo(), // TODO replace with pathInContext
|
||||
old_mapping,
|
||||
old_uri.getQuery());
|
||||
|
||||
String query = _uri.getQuery();
|
||||
if (query == null)
|
||||
|
@ -194,6 +182,7 @@ public class Dispatcher implements RequestDispatcher
|
|||
|
||||
baseRequest.setHttpURI(HttpURI.build(old_uri, _uri.getPath(), _uri.getParam(), query));
|
||||
baseRequest.setContextPath(_contextHandler.getContextPath());
|
||||
baseRequest.setServletPathMapping(null);
|
||||
baseRequest.setServletPath(null);
|
||||
baseRequest.setPathInfo(_pathInContext);
|
||||
|
||||
|
@ -257,16 +246,20 @@ public class Dispatcher implements RequestDispatcher
|
|||
|
||||
private class ForwardAttributes extends Attributes.Wrapper
|
||||
{
|
||||
String _requestURI;
|
||||
String _contextPath;
|
||||
String _servletPath;
|
||||
String _pathInfo;
|
||||
String _query;
|
||||
HttpServletMapping _mapping;
|
||||
private final String _requestURI;
|
||||
private final String _contextPath;
|
||||
private final String _pathInContext;
|
||||
private final ServletPathMapping _servletPathMapping;
|
||||
private final String _query;
|
||||
|
||||
ForwardAttributes(Attributes attributes)
|
||||
public ForwardAttributes(Attributes attributes, String requestURI, String contextPath, String pathInContext, ServletPathMapping mapping, String query)
|
||||
{
|
||||
super(attributes);
|
||||
_requestURI = requestURI;
|
||||
_contextPath = contextPath;
|
||||
_pathInContext = pathInContext;
|
||||
_servletPathMapping = mapping;
|
||||
_query = query;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -277,22 +270,23 @@ public class Dispatcher implements RequestDispatcher
|
|||
switch (key)
|
||||
{
|
||||
case FORWARD_PATH_INFO:
|
||||
return _pathInfo;
|
||||
return _servletPathMapping == null ? _pathInContext : _servletPathMapping.getPathInfo();
|
||||
case FORWARD_REQUEST_URI:
|
||||
return _requestURI;
|
||||
case FORWARD_SERVLET_PATH:
|
||||
return _servletPath;
|
||||
return _servletPathMapping == null ? null : _servletPathMapping.getServletPath();
|
||||
case FORWARD_CONTEXT_PATH:
|
||||
return _contextPath;
|
||||
case FORWARD_QUERY_STRING:
|
||||
return _query;
|
||||
case FORWARD_MAPPING:
|
||||
return _mapping;
|
||||
return _servletPathMapping;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If we are forwarded then we hide include attributes
|
||||
if (key.startsWith(__INCLUDE_PREFIX))
|
||||
return null;
|
||||
|
||||
|
@ -312,18 +306,12 @@ public class Dispatcher implements RequestDispatcher
|
|||
|
||||
if (_named == null)
|
||||
{
|
||||
if (_pathInfo != null)
|
||||
set.add(FORWARD_PATH_INFO);
|
||||
else
|
||||
set.remove(FORWARD_PATH_INFO);
|
||||
set.add(FORWARD_PATH_INFO);
|
||||
set.add(FORWARD_REQUEST_URI);
|
||||
set.add(FORWARD_SERVLET_PATH);
|
||||
set.add(FORWARD_CONTEXT_PATH);
|
||||
set.add(FORWARD_MAPPING);
|
||||
if (_query != null)
|
||||
set.add(FORWARD_QUERY_STRING);
|
||||
else
|
||||
set.remove(FORWARD_QUERY_STRING);
|
||||
set.add(FORWARD_QUERY_STRING);
|
||||
}
|
||||
|
||||
return set;
|
||||
|
@ -332,40 +320,11 @@ public class Dispatcher implements RequestDispatcher
|
|||
@Override
|
||||
public void setAttribute(String key, Object value)
|
||||
{
|
||||
if (_named == null && key.startsWith("javax.servlet."))
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case FORWARD_PATH_INFO:
|
||||
_pathInfo = (String)value;
|
||||
break;
|
||||
case FORWARD_REQUEST_URI:
|
||||
_requestURI = (String)value;
|
||||
break;
|
||||
case FORWARD_SERVLET_PATH:
|
||||
_servletPath = (String)value;
|
||||
break;
|
||||
case FORWARD_CONTEXT_PATH:
|
||||
_contextPath = (String)value;
|
||||
break;
|
||||
case FORWARD_QUERY_STRING:
|
||||
_query = (String)value;
|
||||
break;
|
||||
case FORWARD_MAPPING:
|
||||
_mapping = (HttpServletMapping)value;
|
||||
return;
|
||||
default:
|
||||
if (value == null)
|
||||
_attributes.removeAttribute(key);
|
||||
else
|
||||
_attributes.setAttribute(key, value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (value == null)
|
||||
_attributes.removeAttribute(key);
|
||||
else
|
||||
_attributes.setAttribute(key, value);
|
||||
// Allow any attribute to be set, even if a reserved name. If a reserved
|
||||
// name is set here, it will be hidden by this class during the forward,
|
||||
// but revealed after the forward is complete just as if the reserved name
|
||||
// attribute had be set by the application before the forward.
|
||||
_attributes.setAttribute(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -389,16 +348,19 @@ public class Dispatcher implements RequestDispatcher
|
|||
|
||||
private class IncludeAttributes extends Attributes.Wrapper
|
||||
{
|
||||
String _requestURI;
|
||||
String _contextPath;
|
||||
String _servletPath;
|
||||
String _pathInfo;
|
||||
String _query;
|
||||
HttpServletMapping _mapping;
|
||||
private final String _requestURI;
|
||||
private final String _contextPath;
|
||||
private final String _pathInContext;
|
||||
private ServletPathMapping _servletPathMapping; // Set later by ServletHandler
|
||||
private final String _query;
|
||||
|
||||
IncludeAttributes(Attributes attributes)
|
||||
public IncludeAttributes(Attributes attributes, String requestURI, String contextPath, String pathInContext, String query)
|
||||
{
|
||||
super(attributes);
|
||||
_requestURI = requestURI;
|
||||
_contextPath = contextPath;
|
||||
_pathInContext = pathInContext;
|
||||
_query = query;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -409,9 +371,9 @@ public class Dispatcher implements RequestDispatcher
|
|||
switch (key)
|
||||
{
|
||||
case INCLUDE_PATH_INFO:
|
||||
return _pathInfo;
|
||||
return _servletPathMapping == null ? _pathInContext : _servletPathMapping.getPathInfo();
|
||||
case INCLUDE_SERVLET_PATH:
|
||||
return _servletPath;
|
||||
return _servletPathMapping == null ? null : _servletPathMapping.getServletPath();
|
||||
case INCLUDE_CONTEXT_PATH:
|
||||
return _contextPath;
|
||||
case INCLUDE_QUERY_STRING:
|
||||
|
@ -419,13 +381,11 @@ public class Dispatcher implements RequestDispatcher
|
|||
case INCLUDE_REQUEST_URI:
|
||||
return _requestURI;
|
||||
case INCLUDE_MAPPING:
|
||||
return _mapping;
|
||||
return _servletPathMapping;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (key.startsWith(__INCLUDE_PREFIX))
|
||||
return null;
|
||||
|
||||
return _attributes.getAttribute(key);
|
||||
}
|
||||
|
@ -442,18 +402,12 @@ public class Dispatcher implements RequestDispatcher
|
|||
|
||||
if (_named == null)
|
||||
{
|
||||
if (_pathInfo != null)
|
||||
set.add(INCLUDE_PATH_INFO);
|
||||
else
|
||||
set.remove(INCLUDE_PATH_INFO);
|
||||
set.add(INCLUDE_PATH_INFO);
|
||||
set.add(INCLUDE_REQUEST_URI);
|
||||
set.add(INCLUDE_SERVLET_PATH);
|
||||
set.add(INCLUDE_CONTEXT_PATH);
|
||||
set.add(INCLUDE_MAPPING);
|
||||
if (_query != null)
|
||||
set.add(INCLUDE_QUERY_STRING);
|
||||
else
|
||||
set.remove(INCLUDE_QUERY_STRING);
|
||||
set.add(INCLUDE_QUERY_STRING);
|
||||
}
|
||||
|
||||
return set;
|
||||
|
@ -462,39 +416,11 @@ public class Dispatcher implements RequestDispatcher
|
|||
@Override
|
||||
public void setAttribute(String key, Object value)
|
||||
{
|
||||
if (_named == null && key.startsWith("javax.servlet."))
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case INCLUDE_PATH_INFO:
|
||||
_pathInfo = (String)value;
|
||||
break;
|
||||
case INCLUDE_REQUEST_URI:
|
||||
_requestURI = (String)value;
|
||||
break;
|
||||
case INCLUDE_SERVLET_PATH:
|
||||
_servletPath = (String)value;
|
||||
break;
|
||||
case INCLUDE_CONTEXT_PATH:
|
||||
_contextPath = (String)value;
|
||||
break;
|
||||
case INCLUDE_QUERY_STRING:
|
||||
_query = (String)value;
|
||||
break;
|
||||
case INCLUDE_MAPPING:
|
||||
_mapping = (HttpServletMapping)value;
|
||||
break;
|
||||
default:
|
||||
if (value == null)
|
||||
_attributes.removeAttribute(key);
|
||||
else
|
||||
_attributes.setAttribute(key, value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (value == null)
|
||||
_attributes.removeAttribute(key);
|
||||
if (_servletPathMapping == null && _named == null && INCLUDE_MAPPING.equals(key))
|
||||
_servletPathMapping = (ServletPathMapping)value;
|
||||
else
|
||||
// Allow any attribute to be set, even if a reserved name. If a reserved
|
||||
// name is set here, it will be revealed after the include is complete.
|
||||
_attributes.setAttribute(key, value);
|
||||
}
|
||||
|
||||
|
|
|
@ -63,7 +63,6 @@ import javax.servlet.http.HttpServletRequestWrapper;
|
|||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import javax.servlet.http.HttpUpgradeHandler;
|
||||
import javax.servlet.http.MappingMatch;
|
||||
import javax.servlet.http.Part;
|
||||
import javax.servlet.http.PushBuilder;
|
||||
|
||||
|
@ -83,8 +82,6 @@ import org.eclipse.jetty.http.HttpURI;
|
|||
import org.eclipse.jetty.http.HttpVersion;
|
||||
import org.eclipse.jetty.http.MetaData;
|
||||
import org.eclipse.jetty.http.MimeTypes;
|
||||
import org.eclipse.jetty.http.pathmap.PathSpec;
|
||||
import org.eclipse.jetty.http.pathmap.ServletPathSpec;
|
||||
import org.eclipse.jetty.io.RuntimeIOException;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler.Context;
|
||||
|
@ -193,85 +190,6 @@ public class Request implements HttpServletRequest
|
|||
return null;
|
||||
}
|
||||
|
||||
public static HttpServletMapping getServletMapping(PathSpec pathSpec, String servletPath, String servletName)
|
||||
{
|
||||
final MappingMatch match;
|
||||
final String mapping;
|
||||
if (pathSpec instanceof ServletPathSpec)
|
||||
{
|
||||
switch (pathSpec.getGroup())
|
||||
{
|
||||
case ROOT:
|
||||
match = MappingMatch.CONTEXT_ROOT;
|
||||
mapping = "";
|
||||
break;
|
||||
case DEFAULT:
|
||||
match = MappingMatch.DEFAULT;
|
||||
mapping = "/";
|
||||
break;
|
||||
case EXACT:
|
||||
match = MappingMatch.EXACT;
|
||||
mapping = servletPath.startsWith("/") ? servletPath.substring(1) : servletPath;
|
||||
break;
|
||||
case SUFFIX_GLOB:
|
||||
match = MappingMatch.EXTENSION;
|
||||
int dot = servletPath.lastIndexOf('.');
|
||||
mapping = servletPath.substring(0, dot);
|
||||
break;
|
||||
case PREFIX_GLOB:
|
||||
match = MappingMatch.PATH;
|
||||
mapping = servletPath;
|
||||
break;
|
||||
default:
|
||||
match = null;
|
||||
mapping = servletPath;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
match = null;
|
||||
mapping = servletPath;
|
||||
}
|
||||
|
||||
return new HttpServletMapping()
|
||||
{
|
||||
@Override
|
||||
public String getMatchValue()
|
||||
{
|
||||
return (mapping == null ? "" : mapping);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPattern()
|
||||
{
|
||||
if (pathSpec != null)
|
||||
return pathSpec.getDeclaration();
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServletName()
|
||||
{
|
||||
return (servletName == null ? "" : servletName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MappingMatch getMappingMatch()
|
||||
{
|
||||
return match;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "HttpServletMapping{matchValue=" + getMatchValue() +
|
||||
", pattern=" + getPattern() + ", servletName=" + getServletName() +
|
||||
", mappingMatch=" + getMappingMatch() + "}";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private final HttpChannel _channel;
|
||||
private final List<ServletRequestAttributeListener> _requestAttributeListeners = new ArrayList<>();
|
||||
private final HttpInput _input;
|
||||
|
@ -283,7 +201,7 @@ public class Request implements HttpServletRequest
|
|||
private String _contextPath;
|
||||
private String _servletPath;
|
||||
private String _pathInfo;
|
||||
private PathSpec _pathSpec;
|
||||
private ServletPathMapping _servletPathMapping;
|
||||
private boolean _secure;
|
||||
private String _asyncNotSupportedSource = null;
|
||||
private boolean _newContext;
|
||||
|
@ -1841,7 +1759,6 @@ public class Request implements HttpServletRequest
|
|||
_queryParameters = null;
|
||||
_contentParameters = null;
|
||||
_parameters = null;
|
||||
_pathSpec = null;
|
||||
_contentParamsExtracted = false;
|
||||
_inputState = INPUT_NONE;
|
||||
_multiParts = null;
|
||||
|
@ -1925,50 +1842,67 @@ public class Request implements HttpServletRequest
|
|||
if (getAttribute(AsyncContext.ASYNC_REQUEST_URI) != null)
|
||||
return;
|
||||
|
||||
String requestURI;
|
||||
String contextPath;
|
||||
String servletPath;
|
||||
String pathInfo;
|
||||
String queryString;
|
||||
HttpServletMapping httpServletMapping;
|
||||
|
||||
// Have we been forwarded before?
|
||||
requestURI = (String)getAttribute(RequestDispatcher.FORWARD_REQUEST_URI);
|
||||
if (requestURI != null)
|
||||
{
|
||||
contextPath = (String)getAttribute(RequestDispatcher.FORWARD_CONTEXT_PATH);
|
||||
servletPath = (String)getAttribute(RequestDispatcher.FORWARD_SERVLET_PATH);
|
||||
pathInfo = (String)getAttribute(RequestDispatcher.FORWARD_PATH_INFO);
|
||||
queryString = (String)getAttribute(RequestDispatcher.FORWARD_QUERY_STRING);
|
||||
httpServletMapping = (HttpServletMapping)getAttribute(RequestDispatcher.FORWARD_MAPPING);
|
||||
}
|
||||
else
|
||||
{
|
||||
requestURI = getRequestURI();
|
||||
contextPath = getContextPath();
|
||||
servletPath = getServletPath();
|
||||
pathInfo = getPathInfo();
|
||||
queryString = getQueryString();
|
||||
httpServletMapping = getHttpServletMapping();
|
||||
}
|
||||
|
||||
// Unwrap the _attributes to get the base attributes instance.
|
||||
Attributes baseAttributes;
|
||||
if (_attributes == null)
|
||||
_attributes = baseAttributes = new ServletAttributes();
|
||||
baseAttributes = _attributes = new ServletAttributes();
|
||||
else
|
||||
baseAttributes = Attributes.unwrap(_attributes);
|
||||
|
||||
if (baseAttributes instanceof ServletAttributes)
|
||||
// We cannot use a apply AsyncAttribute via #setAttributes as that
|
||||
// will wrap over any dispatch specific attribute wrappers (eg.
|
||||
// Dispatcher#ForwardAttributes). Async attributes must persist
|
||||
// after the current dispatch, so they must be set under any other
|
||||
// wrappers.
|
||||
|
||||
String fwdRequestURI = (String)getAttribute(RequestDispatcher.FORWARD_REQUEST_URI);
|
||||
if (fwdRequestURI == null)
|
||||
{
|
||||
// Set the AsyncAttributes on the ServletAttributes.
|
||||
ServletAttributes servletAttributes = (ServletAttributes)baseAttributes;
|
||||
servletAttributes.setAsyncAttributes(requestURI, contextPath, servletPath, pathInfo, queryString, httpServletMapping);
|
||||
if (baseAttributes instanceof ServletAttributes)
|
||||
{
|
||||
// The baseAttributes map is our ServletAttributes, so we can set the async
|
||||
// attributes there, under any other wrappers.
|
||||
((ServletAttributes)baseAttributes).setAsyncAttributes(getRequestURI(),
|
||||
getContextPath(),
|
||||
getPathInfo(), // TODO change to pathInContext when cheaply available
|
||||
getServletPathMapping(),
|
||||
getQueryString());
|
||||
}
|
||||
else
|
||||
{
|
||||
// We cannot find our ServletAttributes instance, so just set directly and hope
|
||||
// whatever non jetty wrappers that have been applied will do the right thing.
|
||||
_attributes.setAttribute(AsyncContext.ASYNC_REQUEST_URI, getRequestURI());
|
||||
_attributes.setAttribute(AsyncContext.ASYNC_CONTEXT_PATH, getContextPath());
|
||||
_attributes.setAttribute(AsyncContext.ASYNC_SERVLET_PATH, getServletPath());
|
||||
_attributes.setAttribute(AsyncContext.ASYNC_PATH_INFO, getPathInfo());
|
||||
_attributes.setAttribute(AsyncContext.ASYNC_QUERY_STRING, getQueryString());
|
||||
_attributes.setAttribute(AsyncContext.ASYNC_MAPPING, getHttpServletMapping());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// If ServletAttributes has been replaced just set them on the top level Attributes.
|
||||
AsyncAttributes.applyAsyncAttributes(_attributes, requestURI, contextPath, servletPath, pathInfo, queryString, httpServletMapping);
|
||||
if (baseAttributes instanceof ServletAttributes)
|
||||
{
|
||||
// The baseAttributes map is our ServletAttributes, so we can set the async
|
||||
// attributes there, under any other wrappers.
|
||||
((ServletAttributes)baseAttributes).setAsyncAttributes(fwdRequestURI,
|
||||
(String)getAttribute(RequestDispatcher.FORWARD_CONTEXT_PATH),
|
||||
(String)getAttribute(RequestDispatcher.FORWARD_PATH_INFO),
|
||||
(ServletPathMapping)getAttribute(RequestDispatcher.FORWARD_MAPPING),
|
||||
(String)getAttribute(RequestDispatcher.FORWARD_QUERY_STRING));
|
||||
}
|
||||
else
|
||||
{
|
||||
// We cannot find our ServletAttributes instance, so just set directly and hope
|
||||
// whatever non jetty wrappers that have been applied will do the right thing.
|
||||
_attributes.setAttribute(AsyncContext.ASYNC_REQUEST_URI, fwdRequestURI);
|
||||
_attributes.setAttribute(AsyncContext.ASYNC_CONTEXT_PATH, getAttribute(RequestDispatcher.FORWARD_CONTEXT_PATH));
|
||||
_attributes.setAttribute(AsyncContext.ASYNC_SERVLET_PATH, getAttribute(RequestDispatcher.FORWARD_SERVLET_PATH));
|
||||
_attributes.setAttribute(AsyncContext.ASYNC_PATH_INFO, getAttribute(RequestDispatcher.FORWARD_PATH_INFO));
|
||||
_attributes.setAttribute(AsyncContext.ASYNC_QUERY_STRING, getAttribute(RequestDispatcher.FORWARD_QUERY_STRING));
|
||||
_attributes.setAttribute(AsyncContext.ASYNC_MAPPING, getAttribute(RequestDispatcher.FORWARD_MAPPING));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2411,19 +2345,34 @@ public class Request implements HttpServletRequest
|
|||
throw new ServletException("HttpServletRequest.upgrade() not supported in Jetty");
|
||||
}
|
||||
|
||||
public void setPathSpec(PathSpec pathSpec)
|
||||
/**
|
||||
* Set the servletPathMapping, the servletPath and the pathInfo.
|
||||
* TODO remove the side effect on servletPath and pathInfo by removing those fields.
|
||||
* @param servletPathMapping The mapping used to return from {@link #getHttpServletMapping()}
|
||||
*/
|
||||
public void setServletPathMapping(ServletPathMapping servletPathMapping)
|
||||
{
|
||||
_pathSpec = pathSpec;
|
||||
_servletPathMapping = servletPathMapping;
|
||||
if (servletPathMapping == null)
|
||||
{
|
||||
// TODO reset the servletPath and pathInfo, but currently cannot do that
|
||||
// as we don't know the pathInContext.
|
||||
}
|
||||
else
|
||||
{
|
||||
_servletPath = servletPathMapping.getServletPath();
|
||||
_pathInfo = servletPathMapping.getPathInfo();
|
||||
}
|
||||
}
|
||||
|
||||
public PathSpec getPathSpec()
|
||||
public ServletPathMapping getServletPathMapping()
|
||||
{
|
||||
return _pathSpec;
|
||||
return _servletPathMapping;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpServletMapping getHttpServletMapping()
|
||||
{
|
||||
return Request.getServletMapping(_pathSpec, _servletPath, getServletName());
|
||||
return _servletPathMapping;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,19 +20,24 @@ package org.eclipse.jetty.server;
|
|||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.servlet.http.HttpServletMapping;
|
||||
|
||||
import org.eclipse.jetty.util.Attributes;
|
||||
import org.eclipse.jetty.util.AttributesMap;
|
||||
|
||||
/**
|
||||
* An implementation of Attributes that supports the standard async attributes.
|
||||
*
|
||||
* This implementation delegates to an internal {@link AttributesMap} instance, which
|
||||
* can optionally be wrapped with a {@link AsyncAttributes} instance. This allows async
|
||||
* attributes to be applied underneath any other attribute wrappers.
|
||||
*/
|
||||
public class ServletAttributes implements Attributes
|
||||
{
|
||||
private final Attributes _attributes = new AttributesMap();
|
||||
private AsyncAttributes _asyncAttributes;
|
||||
|
||||
public void setAsyncAttributes(String requestURI, String contextPath, String servletPath, String pathInfo, String queryString, HttpServletMapping httpServletMapping)
|
||||
public void setAsyncAttributes(String requestURI, String contextPath, String pathInContext, ServletPathMapping servletPathMapping, String queryString)
|
||||
{
|
||||
_asyncAttributes = new AsyncAttributes(_attributes, requestURI, contextPath, servletPath, pathInfo, queryString, httpServletMapping);
|
||||
_asyncAttributes = new AsyncAttributes(_attributes, requestURI, contextPath, pathInContext, servletPathMapping, queryString);
|
||||
}
|
||||
|
||||
private Attributes getAttributes()
|
||||
|
|
|
@ -0,0 +1,159 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under
|
||||
// the terms of the Eclipse Public License 2.0 which is available at
|
||||
// https://www.eclipse.org/legal/epl-2.0
|
||||
//
|
||||
// This Source Code may also be made available under the following
|
||||
// Secondary Licenses when the conditions for such availability set
|
||||
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
||||
// the Apache License v2.0 which is available at
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.server;
|
||||
|
||||
import javax.servlet.http.HttpServletMapping;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.MappingMatch;
|
||||
|
||||
import org.eclipse.jetty.http.pathmap.PathSpec;
|
||||
import org.eclipse.jetty.http.pathmap.ServletPathSpec;
|
||||
|
||||
/**
|
||||
* Implementation of HttpServletMapping.
|
||||
*
|
||||
* Represents the application of a {@link ServletPathSpec} to a specific path
|
||||
* that resulted in a mapping to a {@link javax.servlet.Servlet}.
|
||||
* As well as supporting the standard {@link HttpServletMapping} methods, this
|
||||
* class also carries fields, which can be precomputed for the implementation
|
||||
* of {@link HttpServletRequest#getServletPath()} and
|
||||
* {@link HttpServletRequest#getPathInfo()}
|
||||
*/
|
||||
public class ServletPathMapping implements HttpServletMapping
|
||||
{
|
||||
private final MappingMatch _mappingMatch;
|
||||
private final String _matchValue;
|
||||
private final String _pattern;
|
||||
private final String _servletName;
|
||||
private final String _servletPath;
|
||||
private final String _pathInfo;
|
||||
|
||||
public ServletPathMapping(PathSpec pathSpec, String servletName, String pathInContext)
|
||||
{
|
||||
_servletName = (servletName == null ? "" : servletName);
|
||||
_pattern = pathSpec == null ? null : pathSpec.getDeclaration();
|
||||
|
||||
if (pathSpec instanceof ServletPathSpec && pathInContext != null)
|
||||
{
|
||||
switch (pathSpec.getGroup())
|
||||
{
|
||||
case ROOT:
|
||||
_mappingMatch = MappingMatch.CONTEXT_ROOT;
|
||||
_matchValue = "";
|
||||
_servletPath = "";
|
||||
_pathInfo = "/";
|
||||
break;
|
||||
|
||||
case DEFAULT:
|
||||
_mappingMatch = MappingMatch.DEFAULT;
|
||||
_matchValue = "";
|
||||
_servletPath = pathInContext;
|
||||
_pathInfo = null;
|
||||
break;
|
||||
|
||||
case EXACT:
|
||||
_mappingMatch = MappingMatch.EXACT;
|
||||
_matchValue = _pattern.startsWith("/") ? _pattern.substring(1) : _pattern;
|
||||
_servletPath = _pattern;
|
||||
_pathInfo = null;
|
||||
break;
|
||||
|
||||
case PREFIX_GLOB:
|
||||
_mappingMatch = MappingMatch.PATH;
|
||||
_servletPath = pathSpec.getPrefix();
|
||||
// TODO avoid the substring on the known servletPath!
|
||||
_matchValue = _servletPath.startsWith("/") ? _servletPath.substring(1) : _servletPath;
|
||||
_pathInfo = pathSpec.getPathInfo(pathInContext);
|
||||
break;
|
||||
|
||||
case SUFFIX_GLOB:
|
||||
_mappingMatch = MappingMatch.EXTENSION;
|
||||
int dot = pathInContext.lastIndexOf('.');
|
||||
_matchValue = pathInContext.substring(pathInContext.startsWith("/") ? 1 : 0, dot);
|
||||
_servletPath = pathInContext;
|
||||
_pathInfo = null;
|
||||
break;
|
||||
|
||||
case MIDDLE_GLOB:
|
||||
_mappingMatch = null;
|
||||
_matchValue = "";
|
||||
_servletPath = pathInContext;
|
||||
_pathInfo = null;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_mappingMatch = null;
|
||||
_matchValue = "";
|
||||
_servletPath = pathInContext;
|
||||
_pathInfo = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMatchValue()
|
||||
{
|
||||
return _matchValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPattern()
|
||||
{
|
||||
return _pattern;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServletName()
|
||||
{
|
||||
return _servletName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MappingMatch getMappingMatch()
|
||||
{
|
||||
return _mappingMatch;
|
||||
}
|
||||
|
||||
public String getServletPath()
|
||||
{
|
||||
return _servletPath;
|
||||
}
|
||||
|
||||
public String getPathInfo()
|
||||
{
|
||||
return _pathInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "ServletPathMapping{" +
|
||||
"matchValue=" + _matchValue +
|
||||
", pattern=" + _pattern +
|
||||
", servletName=" + _servletName +
|
||||
", mappingMatch=" + _mappingMatch +
|
||||
", servletPath=" + _servletPath +
|
||||
", pathInfo=" + _pathInfo +
|
||||
"}";
|
||||
}
|
||||
}
|
|
@ -47,6 +47,7 @@ import javax.servlet.http.HttpServletMapping;
|
|||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import javax.servlet.http.MappingMatch;
|
||||
import javax.servlet.http.Part;
|
||||
import javax.servlet.http.PushBuilder;
|
||||
|
||||
|
@ -86,6 +87,7 @@ import static org.hamcrest.MatcherAssert.assertThat;
|
|||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
import static org.hamcrest.Matchers.startsWith;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
|
@ -1427,69 +1429,6 @@ public class RequestTest
|
|||
assertThat(response, containsString("Hello World"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHttpServletMapping() throws Exception
|
||||
{
|
||||
String request = "GET / HTTP/1.1\n" +
|
||||
"Host: whatever\n" +
|
||||
"Connection: close\n" +
|
||||
"\n";
|
||||
|
||||
_server.stop();
|
||||
PathMappingHandler handler = new PathMappingHandler(null, null, null);
|
||||
_server.setHandler(handler);
|
||||
_server.start();
|
||||
String response = _connector.getResponse(request);
|
||||
assertTrue(response.startsWith("HTTP/1.1 200 OK"));
|
||||
assertThat("Response body content", response, containsString("HttpServletMapping{matchValue=, pattern=, servletName=, mappingMatch=null}"));
|
||||
_server.stop();
|
||||
|
||||
ServletPathSpec spec = new ServletPathSpec("");
|
||||
handler = new PathMappingHandler(spec, spec.getPathMatch("foo"), "Something");
|
||||
_server.setHandler(handler);
|
||||
_server.start();
|
||||
response = _connector.getResponse(request);
|
||||
assertTrue(response.startsWith("HTTP/1.1 200 OK"));
|
||||
assertThat("Response body content", response, containsString("HttpServletMapping{matchValue=, pattern=, servletName=Something, mappingMatch=CONTEXT_ROOT}"));
|
||||
_server.stop();
|
||||
|
||||
spec = new ServletPathSpec("/");
|
||||
handler = new PathMappingHandler(spec, "", "Default");
|
||||
_server.setHandler(handler);
|
||||
_server.start();
|
||||
response = _connector.getResponse(request);
|
||||
assertTrue(response.startsWith("HTTP/1.1 200 OK"));
|
||||
assertThat("Response body content", response, containsString("HttpServletMapping{matchValue=/, pattern=/, servletName=Default, mappingMatch=DEFAULT}"));
|
||||
_server.stop();
|
||||
|
||||
spec = new ServletPathSpec("/foo/*");
|
||||
handler = new PathMappingHandler(spec, spec.getPathMatch("/foo/bar"), "BarServlet");
|
||||
_server.setHandler(handler);
|
||||
_server.start();
|
||||
response = _connector.getResponse(request);
|
||||
assertTrue(response.startsWith("HTTP/1.1 200 OK"));
|
||||
assertThat("Response body content", response, containsString("HttpServletMapping{matchValue=/foo, pattern=/foo/*, servletName=BarServlet, mappingMatch=PATH}"));
|
||||
_server.stop();
|
||||
|
||||
spec = new ServletPathSpec("*.jsp");
|
||||
handler = new PathMappingHandler(spec, spec.getPathMatch("/foo/bar.jsp"), "JspServlet");
|
||||
_server.setHandler(handler);
|
||||
_server.start();
|
||||
response = _connector.getResponse(request);
|
||||
assertTrue(response.startsWith("HTTP/1.1 200 OK"));
|
||||
assertThat("Response body content", response, containsString("HttpServletMapping{matchValue=/foo/bar, pattern=*.jsp, servletName=JspServlet, mappingMatch=EXTENSION}"));
|
||||
_server.stop();
|
||||
|
||||
spec = new ServletPathSpec("/catalog");
|
||||
handler = new PathMappingHandler(spec, spec.getPathMatch("/catalog"), "CatalogServlet");
|
||||
_server.setHandler(handler);
|
||||
_server.start();
|
||||
response = _connector.getResponse(request);
|
||||
assertTrue(response.startsWith("HTTP/1.1 200 OK"));
|
||||
assertThat("Response body content", response, containsString("HttpServletMapping{matchValue=catalog, pattern=/catalog, servletName=CatalogServlet, mappingMatch=EXACT}"));
|
||||
_server.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCookies() throws Exception
|
||||
{
|
||||
|
@ -1935,6 +1874,92 @@ public class RequestTest
|
|||
assertThat(builder.getHeader("Cookie"), not(containsString("bad")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServletPathMapping() throws Exception
|
||||
{
|
||||
ServletPathSpec spec;
|
||||
String uri;
|
||||
ServletPathMapping m;
|
||||
|
||||
spec = null;
|
||||
uri = null;
|
||||
m = new ServletPathMapping(spec, null, uri);
|
||||
assertThat(m.getMappingMatch(), nullValue());
|
||||
assertThat(m.getMatchValue(), is(""));
|
||||
assertThat(m.getPattern(), nullValue());
|
||||
assertThat(m.getServletName(), is(""));
|
||||
assertThat(m.getServletPath(), nullValue());
|
||||
assertThat(m.getPathInfo(), nullValue());
|
||||
|
||||
spec = new ServletPathSpec("");
|
||||
uri = "/";
|
||||
m = new ServletPathMapping(spec, "Something", uri);
|
||||
assertThat(m.getMappingMatch(), is(MappingMatch.CONTEXT_ROOT));
|
||||
assertThat(m.getMatchValue(), is(""));
|
||||
assertThat(m.getPattern(), is(""));
|
||||
assertThat(m.getServletName(), is("Something"));
|
||||
assertThat(m.getServletPath(), is(spec.getPathMatch(uri)));
|
||||
assertThat(m.getPathInfo(), is(spec.getPathInfo(uri)));
|
||||
|
||||
spec = new ServletPathSpec("/");
|
||||
uri = "/some/path";
|
||||
m = new ServletPathMapping(spec, "Default", uri);
|
||||
assertThat(m.getMappingMatch(), is(MappingMatch.DEFAULT));
|
||||
assertThat(m.getMatchValue(), is(""));
|
||||
assertThat(m.getPattern(), is("/"));
|
||||
assertThat(m.getServletName(), is("Default"));
|
||||
assertThat(m.getServletPath(), is(spec.getPathMatch(uri)));
|
||||
assertThat(m.getPathInfo(), is(spec.getPathInfo(uri)));
|
||||
|
||||
spec = new ServletPathSpec("/foo/*");
|
||||
uri = "/foo/bar";
|
||||
m = new ServletPathMapping(spec, "FooServlet", uri);
|
||||
assertThat(m.getMappingMatch(), is(MappingMatch.PATH));
|
||||
assertThat(m.getMatchValue(), is("foo"));
|
||||
assertThat(m.getPattern(), is("/foo/*"));
|
||||
assertThat(m.getServletName(), is("FooServlet"));
|
||||
assertThat(m.getServletPath(), is(spec.getPathMatch(uri)));
|
||||
assertThat(m.getPathInfo(), is(spec.getPathInfo(uri)));
|
||||
|
||||
uri = "/foo/";
|
||||
m = new ServletPathMapping(spec, "FooServlet", uri);
|
||||
assertThat(m.getMappingMatch(), is(MappingMatch.PATH));
|
||||
assertThat(m.getMatchValue(), is("foo"));
|
||||
assertThat(m.getPattern(), is("/foo/*"));
|
||||
assertThat(m.getServletName(), is("FooServlet"));
|
||||
assertThat(m.getServletPath(), is(spec.getPathMatch(uri)));
|
||||
assertThat(m.getPathInfo(), is(spec.getPathInfo(uri)));
|
||||
|
||||
uri = "/foo";
|
||||
m = new ServletPathMapping(spec, "FooServlet", uri);
|
||||
assertThat(m.getMappingMatch(), is(MappingMatch.PATH));
|
||||
assertThat(m.getMatchValue(), is("foo"));
|
||||
assertThat(m.getPattern(), is("/foo/*"));
|
||||
assertThat(m.getServletName(), is("FooServlet"));
|
||||
assertThat(m.getServletPath(), is(spec.getPathMatch(uri)));
|
||||
assertThat(m.getPathInfo(), is(spec.getPathInfo(uri)));
|
||||
|
||||
spec = new ServletPathSpec("*.jsp");
|
||||
uri = "/foo/bar.jsp";
|
||||
m = new ServletPathMapping(spec, "JspServlet", uri);
|
||||
assertThat(m.getMappingMatch(), is(MappingMatch.EXTENSION));
|
||||
assertThat(m.getMatchValue(), is("foo/bar"));
|
||||
assertThat(m.getPattern(), is("*.jsp"));
|
||||
assertThat(m.getServletName(), is("JspServlet"));
|
||||
assertThat(m.getServletPath(), is(spec.getPathMatch(uri)));
|
||||
assertThat(m.getPathInfo(), is(spec.getPathInfo(uri)));
|
||||
|
||||
spec = new ServletPathSpec("/catalog");
|
||||
uri = "/catalog";
|
||||
m = new ServletPathMapping(spec, "CatalogServlet", uri);
|
||||
assertThat(m.getMappingMatch(), is(MappingMatch.EXACT));
|
||||
assertThat(m.getMatchValue(), is("catalog"));
|
||||
assertThat(m.getPattern(), is("/catalog"));
|
||||
assertThat(m.getServletName(), is("CatalogServlet"));
|
||||
assertThat(m.getServletPath(), is(spec.getPathMatch(uri)));
|
||||
assertThat(m.getPathInfo(), is(spec.getPathInfo(uri)));
|
||||
}
|
||||
|
||||
interface RequestTester
|
||||
{
|
||||
boolean check(HttpServletRequest request, HttpServletResponse response) throws IOException;
|
||||
|
@ -2169,7 +2194,6 @@ public class RequestTest
|
|||
{
|
||||
((Request)request).setHandled(true);
|
||||
baseRequest.setServletPath(_servletPath);
|
||||
baseRequest.setPathSpec(_spec);
|
||||
if (_servletName != null)
|
||||
baseRequest.setUserIdentityScope(new TestUserIdentityScope(null, null, _servletName));
|
||||
HttpServletMapping mapping = baseRequest.getHttpServletMapping();
|
||||
|
|
|
@ -35,7 +35,6 @@ import org.eclipse.jetty.http.HttpContent;
|
|||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.MimeTypes;
|
||||
import org.eclipse.jetty.http.PreEncodedHttpField;
|
||||
import org.eclipse.jetty.http.pathmap.MappedResource;
|
||||
import org.eclipse.jetty.server.CachedContentFactory;
|
||||
import org.eclipse.jetty.server.ResourceContentFactory;
|
||||
import org.eclipse.jetty.server.ResourceService;
|
||||
|
@ -500,9 +499,9 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory, Welc
|
|||
|
||||
if ((_welcomeServlets || _welcomeExactServlets) && welcomeServlet == null)
|
||||
{
|
||||
MappedResource<ServletHolder> entry = _servletHandler.getMappedServlet(welcomeInContext);
|
||||
ServletHandler.MappedServlet entry = _servletHandler.getMappedServlet(welcomeInContext);
|
||||
@SuppressWarnings("ReferenceEquality")
|
||||
boolean isDefaultHolder = (entry.getResource() != _defaultHolder);
|
||||
boolean isDefaultHolder = (entry.getServletHolder() != _defaultHolder);
|
||||
if (entry != null && isDefaultHolder &&
|
||||
(_welcomeServlets || (_welcomeExactServlets && entry.getPathSpec().getDeclaration().equals(welcomeInContext))))
|
||||
welcomeServlet = welcomeInContext;
|
||||
|
|
|
@ -31,7 +31,6 @@ import javax.servlet.http.HttpServletRequest;
|
|||
import javax.servlet.http.HttpServletRequestWrapper;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.eclipse.jetty.http.pathmap.MappedResource;
|
||||
import org.eclipse.jetty.server.Dispatcher;
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
|
@ -71,7 +70,7 @@ public class Invoker extends HttpServlet
|
|||
|
||||
private ContextHandler _contextHandler;
|
||||
private ServletHandler _servletHandler;
|
||||
private MappedResource<ServletHolder> _invokerEntry;
|
||||
private ServletHandler.MappedServlet _invokerEntry;
|
||||
private Map<String, String> _parameters;
|
||||
private boolean _nonContextServlets;
|
||||
private boolean _verbose;
|
||||
|
@ -171,12 +170,12 @@ public class Invoker extends HttpServlet
|
|||
|
||||
// Check for existing mapping (avoid threaded race).
|
||||
String path = URIUtil.addPaths(servletPath, servlet);
|
||||
MappedResource<ServletHolder> entry = _servletHandler.getMappedServlet(path);
|
||||
ServletHandler.MappedServlet entry = _servletHandler.getMappedServlet(path);
|
||||
|
||||
if (entry != null && !entry.equals(_invokerEntry))
|
||||
{
|
||||
// Use the holder
|
||||
holder = (ServletHolder)entry.getResource();
|
||||
holder = (ServletHolder)entry.getServletHolder();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -26,7 +26,6 @@ import java.util.EnumSet;
|
|||
import java.util.EventListener;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
import java.util.Set;
|
||||
|
@ -57,6 +56,7 @@ import org.eclipse.jetty.http.pathmap.ServletPathSpec;
|
|||
import org.eclipse.jetty.security.IdentityService;
|
||||
import org.eclipse.jetty.security.SecurityHandler;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.server.ServletPathMapping;
|
||||
import org.eclipse.jetty.server.ServletRequestHttpWrapper;
|
||||
import org.eclipse.jetty.server.ServletResponseHttpWrapper;
|
||||
import org.eclipse.jetty.server.UserIdentity;
|
||||
|
@ -92,8 +92,6 @@ public class ServletHandler extends ScopedHandler
|
|||
{
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ServletHandler.class);
|
||||
|
||||
public static final String __DEFAULT_SERVLET = "default";
|
||||
|
||||
private ServletContextHandler _contextHandler;
|
||||
private ServletContext _servletContext;
|
||||
private FilterHolder[] _filters = new FilterHolder[0];
|
||||
|
@ -113,8 +111,8 @@ public class ServletHandler extends ScopedHandler
|
|||
private List<FilterMapping> _filterPathMappings;
|
||||
private MultiMap<FilterMapping> _filterNameMappings;
|
||||
|
||||
private final Map<String, ServletHolder> _servletNameMap = new HashMap<>();
|
||||
private PathMappings<ServletHolder> _servletPathMap;
|
||||
private final Map<String, MappedServlet> _servletNameMap = new HashMap<>();
|
||||
private PathMappings<MappedServlet> _servletPathMap;
|
||||
|
||||
private ListenerHolder[] _listeners = new ListenerHolder[0];
|
||||
private boolean _initialized = false;
|
||||
|
@ -167,7 +165,7 @@ public class ServletHandler extends ScopedHandler
|
|||
LOG.debug("Adding Default404Servlet to {}", this);
|
||||
addServletWithMapping(Default404Servlet.class, "/");
|
||||
updateMappings();
|
||||
getServletMapping("/").setDefault(true);
|
||||
getServletMapping("/").setFromDefaultDescriptor(true);
|
||||
}
|
||||
|
||||
if (isFilterChainsCached())
|
||||
|
@ -247,13 +245,7 @@ public class ServletHandler extends ScopedHandler
|
|||
//remove all of the mappings that were for non-embedded filters
|
||||
_filterNameMap.remove(filter.getName());
|
||||
//remove any mappings associated with this filter
|
||||
ListIterator<FilterMapping> fmitor = filterMappings.listIterator();
|
||||
while (fmitor.hasNext())
|
||||
{
|
||||
FilterMapping fm = fmitor.next();
|
||||
if (fm.getFilterName().equals(filter.getName()))
|
||||
fmitor.remove();
|
||||
}
|
||||
filterMappings.removeIf(fm -> fm.getFilterName().equals(filter.getName()));
|
||||
}
|
||||
else
|
||||
filterHolders.add(filter); //only retain embedded
|
||||
|
@ -261,10 +253,8 @@ public class ServletHandler extends ScopedHandler
|
|||
}
|
||||
|
||||
//Retain only filters and mappings that were added using jetty api (ie Source.EMBEDDED)
|
||||
FilterHolder[] fhs = (FilterHolder[])LazyList.toArray(filterHolders, FilterHolder.class);
|
||||
_filters = fhs;
|
||||
FilterMapping[] fms = (FilterMapping[])LazyList.toArray(filterMappings, FilterMapping.class);
|
||||
_filterMappings = fms;
|
||||
_filters = (FilterHolder[])LazyList.toArray(filterHolders, FilterHolder.class);
|
||||
_filterMappings = (FilterMapping[])LazyList.toArray(filterMappings, FilterMapping.class);
|
||||
|
||||
_matchAfterIndex = (_filterMappings == null || _filterMappings.length == 0 ? -1 : _filterMappings.length - 1);
|
||||
_matchBeforeIndex = -1;
|
||||
|
@ -291,13 +281,7 @@ public class ServletHandler extends ScopedHandler
|
|||
//remove from servlet name map
|
||||
_servletNameMap.remove(servlet.getName());
|
||||
//remove any mappings associated with this servlet
|
||||
ListIterator<ServletMapping> smitor = servletMappings.listIterator();
|
||||
while (smitor.hasNext())
|
||||
{
|
||||
ServletMapping sm = smitor.next();
|
||||
if (sm.getServletName().equals(servlet.getName()))
|
||||
smitor.remove();
|
||||
}
|
||||
servletMappings.removeIf(sm -> sm.getServletName().equals(servlet.getName()));
|
||||
}
|
||||
else
|
||||
servletHolders.add(servlet); //only retain embedded
|
||||
|
@ -305,10 +289,8 @@ public class ServletHandler extends ScopedHandler
|
|||
}
|
||||
|
||||
//Retain only Servlets and mappings added via jetty apis (ie Source.EMBEDDED)
|
||||
ServletHolder[] shs = (ServletHolder[])LazyList.toArray(servletHolders, ServletHolder.class);
|
||||
_servlets = shs;
|
||||
ServletMapping[] sms = (ServletMapping[])LazyList.toArray(servletMappings, ServletMapping.class);
|
||||
_servletMappings = sms;
|
||||
_servlets = (ServletHolder[])LazyList.toArray(servletHolders, ServletHolder.class);
|
||||
_servletMappings = (ServletMapping[])LazyList.toArray(servletMappings, ServletMapping.class);
|
||||
|
||||
if (_contextHandler != null)
|
||||
_contextHandler.contextDestroyed();
|
||||
|
@ -332,8 +314,7 @@ public class ServletHandler extends ScopedHandler
|
|||
listenerHolders.add(listener);
|
||||
}
|
||||
}
|
||||
ListenerHolder[] listeners = (ListenerHolder[])LazyList.toArray(listenerHolders, ListenerHolder.class);
|
||||
_listeners = listeners;
|
||||
_listeners = (ListenerHolder[])LazyList.toArray(listenerHolders, ListenerHolder.class);
|
||||
|
||||
//will be regenerated on next start
|
||||
_filterPathMappings = null;
|
||||
|
@ -425,50 +406,40 @@ public class ServletHandler extends ScopedHandler
|
|||
|
||||
public ServletHolder getServlet(String name)
|
||||
{
|
||||
return _servletNameMap.get(name);
|
||||
MappedServlet mapped = _servletNameMap.get(name);
|
||||
if (mapped != null)
|
||||
return mapped.getServletHolder();
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doScope(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
{
|
||||
// Get the base requests
|
||||
final String old_servlet_path = baseRequest.getServletPath();
|
||||
final String old_path_info = baseRequest.getPathInfo();
|
||||
final PathSpec old_path_spec = baseRequest.getPathSpec();
|
||||
final ServletPathMapping old_servlet_path_mapping = baseRequest.getServletPathMapping();
|
||||
|
||||
DispatcherType type = baseRequest.getDispatcherType();
|
||||
|
||||
ServletHolder servletHolder = null;
|
||||
UserIdentity.Scope oldScope = null;
|
||||
|
||||
MappedResource<ServletHolder> mapping = getMappedServlet(target);
|
||||
if (mapping != null)
|
||||
MappedServlet mappedServlet = getMappedServlet(target);
|
||||
if (mappedServlet != null)
|
||||
{
|
||||
servletHolder = mapping.getResource();
|
||||
|
||||
if (mapping.getPathSpec() != null)
|
||||
servletHolder = mappedServlet.getServletHolder();
|
||||
ServletPathMapping servletPathMapping = mappedServlet.getServletPathMapping(target);
|
||||
if (servletPathMapping != null)
|
||||
{
|
||||
PathSpec pathSpec = mapping.getPathSpec();
|
||||
String servletPath = pathSpec.getPathMatch(target);
|
||||
String pathInfo = pathSpec.getPathInfo(target);
|
||||
|
||||
// Setting the servletPathMapping also provides the servletPath and pathInfo
|
||||
if (DispatcherType.INCLUDE.equals(type))
|
||||
{
|
||||
baseRequest.setAttribute(RequestDispatcher.INCLUDE_SERVLET_PATH, servletPath);
|
||||
baseRequest.setAttribute(RequestDispatcher.INCLUDE_PATH_INFO, pathInfo);
|
||||
baseRequest.setAttribute(RequestDispatcher.INCLUDE_MAPPING, Request.getServletMapping(pathSpec, servletPath, servletHolder.getName()));
|
||||
}
|
||||
baseRequest.setAttribute(RequestDispatcher.INCLUDE_MAPPING, servletPathMapping);
|
||||
else
|
||||
{
|
||||
baseRequest.setPathSpec(pathSpec);
|
||||
baseRequest.setServletPath(servletPath);
|
||||
baseRequest.setPathInfo(pathInfo);
|
||||
}
|
||||
baseRequest.setServletPathMapping(servletPathMapping);
|
||||
}
|
||||
}
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("servlet {}|{}|{} -> {}", baseRequest.getContextPath(), baseRequest.getServletPath(), baseRequest.getPathInfo(), servletHolder);
|
||||
LOG.debug("servlet {}|{}|{}|{} -> {}", baseRequest.getContextPath(), baseRequest.getServletPath(), baseRequest.getPathInfo(), baseRequest.getHttpServletMapping(), servletHolder);
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -484,11 +455,7 @@ public class ServletHandler extends ScopedHandler
|
|||
baseRequest.setUserIdentityScope(oldScope);
|
||||
|
||||
if (!(DispatcherType.INCLUDE.equals(type)))
|
||||
{
|
||||
baseRequest.setServletPath(old_servlet_path);
|
||||
baseRequest.setPathInfo(old_path_info);
|
||||
baseRequest.setPathSpec(old_path_spec);
|
||||
}
|
||||
baseRequest.setServletPathMapping(old_servlet_path_mapping);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -550,34 +517,33 @@ public class ServletHandler extends ScopedHandler
|
|||
}
|
||||
|
||||
/**
|
||||
* ServletHolder matching path.
|
||||
* Get MappedServlet for target.
|
||||
*
|
||||
* @param target Path within _context or servlet name
|
||||
* @return MappedResource to the ServletHolder. Named servlets have a null PathSpec
|
||||
* @return MappedServlet matched by path or name. Named servlets have a null PathSpec
|
||||
*/
|
||||
public MappedResource<ServletHolder> getMappedServlet(String target)
|
||||
public MappedServlet getMappedServlet(String target)
|
||||
{
|
||||
if (target.startsWith("/"))
|
||||
{
|
||||
if (_servletPathMap == null)
|
||||
return null;
|
||||
return _servletPathMap.getMatch(target);
|
||||
|
||||
MappedResource<MappedServlet> match = _servletPathMap.getMatch(target);
|
||||
if (match == null)
|
||||
return null;
|
||||
return match.getResource();
|
||||
}
|
||||
|
||||
if (_servletNameMap == null)
|
||||
return null;
|
||||
ServletHolder holder = _servletNameMap.get(target);
|
||||
if (holder == null)
|
||||
return null;
|
||||
return new MappedResource<>(null, holder);
|
||||
return _servletNameMap.get(target);
|
||||
}
|
||||
|
||||
protected FilterChain getFilterChain(Request baseRequest, String pathInContext, ServletHolder servletHolder)
|
||||
private FilterChain getFilterChain(Request baseRequest, String pathInContext, ServletHolder servletHolder)
|
||||
{
|
||||
String key = pathInContext == null ? servletHolder.getName() : pathInContext;
|
||||
int dispatch = FilterMapping.dispatch(baseRequest.getDispatcherType());
|
||||
|
||||
if (_filterChainsCached && _chainCache != null)
|
||||
if (_filterChainsCached)
|
||||
{
|
||||
FilterChain chain = _chainCache[dispatch].get(key);
|
||||
if (chain != null)
|
||||
|
@ -624,8 +590,7 @@ public class ServletHandler extends ScopedHandler
|
|||
FilterChain chain = null;
|
||||
if (_filterChainsCached)
|
||||
{
|
||||
if (!filters.isEmpty())
|
||||
chain = newCachedChain(filters, servletHolder);
|
||||
chain = newCachedChain(filters, servletHolder);
|
||||
|
||||
final Map<String, FilterChain> cache = _chainCache[dispatch];
|
||||
final Queue<String> lru = _chainLRU[dispatch];
|
||||
|
@ -648,7 +613,7 @@ public class ServletHandler extends ScopedHandler
|
|||
cache.put(key, chain);
|
||||
lru.add(key);
|
||||
}
|
||||
else if (!filters.isEmpty())
|
||||
else
|
||||
chain = new Chain(baseRequest, filters, servletHolder);
|
||||
|
||||
return chain;
|
||||
|
@ -1133,7 +1098,7 @@ public class ServletHandler extends ScopedHandler
|
|||
if (mappings == null || mappings.length == 0)
|
||||
{
|
||||
setFilterMappings(insertFilterMapping(mapping, 0, false));
|
||||
if (source != null && source == Source.JAVAX_API)
|
||||
if (source == Source.JAVAX_API)
|
||||
_matchAfterIndex = 0;
|
||||
}
|
||||
else
|
||||
|
@ -1141,7 +1106,7 @@ public class ServletHandler extends ScopedHandler
|
|||
//there are existing entries. If this is a programmatic filtermapping, it is added at the end of the list.
|
||||
//If this is a normal filtermapping, it is inserted after all the other filtermappings (matchBefores and normals),
|
||||
//but before the first matchAfter filtermapping.
|
||||
if (source != null && Source.JAVAX_API == source)
|
||||
if (Source.JAVAX_API == source)
|
||||
{
|
||||
setFilterMappings(insertFilterMapping(mapping, mappings.length - 1, false));
|
||||
if (_matchAfterIndex < 0)
|
||||
|
@ -1177,12 +1142,12 @@ public class ServletHandler extends ScopedHandler
|
|||
if (mappings == null || mappings.length == 0)
|
||||
{
|
||||
setFilterMappings(insertFilterMapping(mapping, 0, false));
|
||||
if (source != null && Source.JAVAX_API == source)
|
||||
if (Source.JAVAX_API == source)
|
||||
_matchBeforeIndex = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (source != null && Source.JAVAX_API == source)
|
||||
if (Source.JAVAX_API == source)
|
||||
{
|
||||
//programmatically defined filter mappings are prepended to mapping list in the order
|
||||
//in which they were defined. In other words, insert this mapping at the tail of the
|
||||
|
@ -1281,7 +1246,7 @@ public class ServletHandler extends ScopedHandler
|
|||
// update the maps
|
||||
for (ServletHolder servlet : _servlets)
|
||||
{
|
||||
_servletNameMap.put(servlet.getName(), servlet);
|
||||
_servletNameMap.put(servlet.getName(), new MappedServlet(null, servlet));
|
||||
servlet.setServletHandler(this);
|
||||
}
|
||||
}
|
||||
|
@ -1321,13 +1286,13 @@ public class ServletHandler extends ScopedHandler
|
|||
}
|
||||
|
||||
// Map servlet paths to holders
|
||||
if (_servletMappings == null || _servletNameMap == null)
|
||||
if (_servletMappings == null)
|
||||
{
|
||||
_servletPathMap = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
PathMappings<ServletHolder> pm = new PathMappings<>();
|
||||
PathMappings<MappedServlet> pm = new PathMappings<>();
|
||||
|
||||
//create a map of paths to set of ServletMappings that define that mapping
|
||||
HashMap<String, List<ServletMapping>> sms = new HashMap<>();
|
||||
|
@ -1338,12 +1303,7 @@ public class ServletHandler extends ScopedHandler
|
|||
{
|
||||
for (String pathSpec : pathSpecs)
|
||||
{
|
||||
List<ServletMapping> mappings = sms.get(pathSpec);
|
||||
if (mappings == null)
|
||||
{
|
||||
mappings = new ArrayList<>();
|
||||
sms.put(pathSpec, mappings);
|
||||
}
|
||||
List<ServletMapping> mappings = sms.computeIfAbsent(pathSpec, k -> new ArrayList<>());
|
||||
mappings.add(servletMapping);
|
||||
}
|
||||
}
|
||||
|
@ -1360,7 +1320,7 @@ public class ServletHandler extends ScopedHandler
|
|||
for (ServletMapping mapping : mappings)
|
||||
{
|
||||
//Get servlet associated with the mapping and check it is enabled
|
||||
ServletHolder servletHolder = _servletNameMap.get(mapping.getServletName());
|
||||
ServletHolder servletHolder = getServlet(mapping.getServletName());
|
||||
if (servletHolder == null)
|
||||
throw new IllegalStateException("No such servlet: " + mapping.getServletName());
|
||||
//if the servlet related to the mapping is not enabled, skip it from consideration
|
||||
|
@ -1374,7 +1334,7 @@ public class ServletHandler extends ScopedHandler
|
|||
{
|
||||
//already have a candidate - only accept another one
|
||||
//if the candidate is a default, or we're allowing duplicate mappings
|
||||
if (finalMapping.isDefault())
|
||||
if (finalMapping.isFromDefaultDescriptor())
|
||||
finalMapping = mapping;
|
||||
else if (isAllowDuplicateMappings())
|
||||
{
|
||||
|
@ -1384,9 +1344,9 @@ public class ServletHandler extends ScopedHandler
|
|||
else
|
||||
{
|
||||
//existing candidate isn't a default, if the one we're looking at isn't a default either, then its an error
|
||||
if (!mapping.isDefault())
|
||||
if (!mapping.isFromDefaultDescriptor())
|
||||
{
|
||||
ServletHolder finalMappedServlet = _servletNameMap.get(finalMapping.getServletName());
|
||||
ServletHolder finalMappedServlet = getServlet(finalMapping.getServletName());
|
||||
throw new IllegalStateException("Multiple servlets map to path " +
|
||||
pathSpec + ": " +
|
||||
finalMappedServlet.getName() + "[mapped:" + finalMapping.getSource() + "]," +
|
||||
|
@ -1403,22 +1363,21 @@ public class ServletHandler extends ScopedHandler
|
|||
pathSpec,
|
||||
finalMapping.getSource(),
|
||||
finalMapping.getServletName(),
|
||||
_servletNameMap.get(finalMapping.getServletName()).getSource());
|
||||
getServlet(finalMapping.getServletName()).getSource());
|
||||
|
||||
pm.put(new ServletPathSpec(pathSpec), _servletNameMap.get(finalMapping.getServletName()));
|
||||
ServletPathSpec servletPathSpec = new ServletPathSpec(pathSpec);
|
||||
MappedServlet mappedServlet = new MappedServlet(servletPathSpec, getServlet(finalMapping.getServletName()));
|
||||
pm.put(servletPathSpec, mappedServlet);
|
||||
}
|
||||
|
||||
_servletPathMap = pm;
|
||||
}
|
||||
|
||||
// flush filter chain cache
|
||||
if (_chainCache != null)
|
||||
for (int i = _chainCache.length; i-- > 0; )
|
||||
{
|
||||
for (int i = _chainCache.length; i-- > 0; )
|
||||
{
|
||||
if (_chainCache[i] != null)
|
||||
_chainCache[i].clear();
|
||||
}
|
||||
if (_chainCache[i] != null)
|
||||
_chainCache[i].clear();
|
||||
}
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
|
@ -1453,28 +1412,26 @@ public class ServletHandler extends ScopedHandler
|
|||
{
|
||||
if (_filters == null)
|
||||
return false;
|
||||
boolean found = false;
|
||||
for (FilterHolder f : _filters)
|
||||
{
|
||||
if (f == holder)
|
||||
found = true;
|
||||
return true;
|
||||
}
|
||||
return found;
|
||||
return false;
|
||||
}
|
||||
|
||||
protected synchronized boolean containsServletHolder(ServletHolder holder)
|
||||
{
|
||||
if (_servlets == null)
|
||||
return false;
|
||||
boolean found = false;
|
||||
for (ServletHolder s : _servlets)
|
||||
{
|
||||
@SuppressWarnings("ReferenceEquality")
|
||||
boolean foundServletHolder = (s == holder);
|
||||
if (foundServletHolder)
|
||||
found = true;
|
||||
return true;
|
||||
}
|
||||
return found;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1731,6 +1688,68 @@ public class ServletHandler extends ScopedHandler
|
|||
_contextHandler.destroyListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* A mapping of a servlet by pathSpec or by name
|
||||
*/
|
||||
public static class MappedServlet
|
||||
{
|
||||
private final PathSpec _pathSpec;
|
||||
private final ServletHolder _servletHolder;
|
||||
private final ServletPathMapping _servletPathMapping;
|
||||
|
||||
MappedServlet(PathSpec pathSpec, ServletHolder servletHolder)
|
||||
{
|
||||
_pathSpec = pathSpec;
|
||||
_servletHolder = servletHolder;
|
||||
|
||||
// Create the HttpServletMapping only once if possible.
|
||||
if (pathSpec instanceof ServletPathSpec)
|
||||
{
|
||||
switch (pathSpec.getGroup())
|
||||
{
|
||||
case EXACT:
|
||||
case ROOT:
|
||||
_servletPathMapping = new ServletPathMapping(_pathSpec, _servletHolder.getName(), _pathSpec.getPrefix());
|
||||
break;
|
||||
default:
|
||||
_servletPathMapping = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_servletPathMapping = null;
|
||||
}
|
||||
}
|
||||
|
||||
public PathSpec getPathSpec()
|
||||
{
|
||||
return _pathSpec;
|
||||
}
|
||||
|
||||
public ServletHolder getServletHolder()
|
||||
{
|
||||
return _servletHolder;
|
||||
}
|
||||
|
||||
public ServletPathMapping getServletPathMapping(String pathInContext)
|
||||
{
|
||||
if (_servletPathMapping != null)
|
||||
return _servletPathMapping;
|
||||
if (_pathSpec != null)
|
||||
return new ServletPathMapping(_pathSpec, _servletHolder.getName(), pathInContext);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("MappedServlet%x{%s->%s}",
|
||||
hashCode(), _pathSpec == null ? null : _pathSpec.getDeclaration(), _servletHolder);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public static class Default404Servlet extends HttpServlet
|
||||
{
|
||||
|
|
|
@ -918,7 +918,7 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
|
|||
if (mapping != null)
|
||||
{
|
||||
//if the servlet mapping was from a default descriptor, then allow it to be overridden
|
||||
if (!mapping.isDefault())
|
||||
if (!mapping.isFromDefaultDescriptor())
|
||||
{
|
||||
if (clash == null)
|
||||
clash = new HashSet<>();
|
||||
|
|
|
@ -104,12 +104,12 @@ public class ServletMapping
|
|||
}
|
||||
|
||||
@ManagedAttribute(value = "default", readonly = true)
|
||||
public boolean isDefault()
|
||||
public boolean isFromDefaultDescriptor()
|
||||
{
|
||||
return _default;
|
||||
}
|
||||
|
||||
public void setDefault(boolean fromDefault)
|
||||
public void setFromDefaultDescriptor(boolean fromDefault)
|
||||
{
|
||||
_default = fromDefault;
|
||||
}
|
||||
|
|
|
@ -257,7 +257,7 @@ public class AsyncContextTest
|
|||
assertThat("async run attr query string", responseBody, containsString("async:run:attr:queryString:dispatch=true"));
|
||||
assertThat("async run context path", responseBody, containsString("async:run:attr:contextPath:/ctx"));
|
||||
assertThat("async run request uri has correct encoding", responseBody, containsString("async:run:attr:requestURI:/ctx/test/hello%2fthere"));
|
||||
assertThat("http servlet mapping matchValue is correct", responseBody, containsString("async:run:attr:mapping:matchValue:/test"));
|
||||
assertThat("http servlet mapping matchValue is correct", responseBody, containsString("async:run:attr:mapping:matchValue:test"));
|
||||
assertThat("http servlet mapping pattern is correct", responseBody, containsString("async:run:attr:mapping:pattern:/test/*"));
|
||||
assertThat("http servlet mapping servletName is correct", responseBody, containsString("async:run:attr:mapping:servletName:"));
|
||||
assertThat("http servlet mapping mappingMatch is correct", responseBody, containsString("async:run:attr:mapping:mappingMatch:PATH"));
|
||||
|
|
|
@ -170,6 +170,43 @@ public class DispatcherTest
|
|||
assertEquals(expected, responses);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNamedForward() throws Exception
|
||||
{
|
||||
_contextHandler.addServlet(NamedForwardServlet.class, "/forward/*");
|
||||
String echo = _contextHandler.addServlet(EchoURIServlet.class, "/echo/*").getName();
|
||||
|
||||
String expected =
|
||||
"HTTP/1.1 200 OK\r\n" +
|
||||
"Content-Type: text/plain\r\n" +
|
||||
"Content-Length: 62\r\n" +
|
||||
"\r\n" +
|
||||
"/context\r\n" +
|
||||
"/forward\r\n" +
|
||||
"/info\r\n" +
|
||||
"/context/forward/info;param=value\r\n";
|
||||
String responses = _connector.getResponse("GET /context/forward/info;param=value?name=" + echo + " HTTP/1.0\n\n");
|
||||
assertEquals(expected, responses);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNamedInclude() throws Exception
|
||||
{
|
||||
_contextHandler.addServlet(NamedIncludeServlet.class, "/include/*");
|
||||
String echo = _contextHandler.addServlet(EchoURIServlet.class, "/echo/*").getName();
|
||||
|
||||
String expected =
|
||||
"HTTP/1.1 200 OK\r\n" +
|
||||
"Content-Length: 62\r\n" +
|
||||
"\r\n" +
|
||||
"/context\r\n" +
|
||||
"/include\r\n" +
|
||||
"/info\r\n" +
|
||||
"/context/include/info;param=value\r\n";
|
||||
String responses = _connector.getResponse("GET /context/include/info;param=value?name=" + echo + " HTTP/1.0\n\n");
|
||||
assertEquals(expected, responses);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testForwardWithBadParams() throws Exception
|
||||
{
|
||||
|
@ -507,6 +544,24 @@ public class DispatcherTest
|
|||
}
|
||||
}
|
||||
|
||||
public static class NamedForwardServlet extends HttpServlet implements Servlet
|
||||
{
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
||||
{
|
||||
getServletContext().getNamedDispatcher(request.getParameter("name")).forward(request, response);
|
||||
}
|
||||
}
|
||||
|
||||
public static class NamedIncludeServlet extends HttpServlet implements Servlet
|
||||
{
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
||||
{
|
||||
getServletContext().getNamedDispatcher(request.getParameter("name")).include(request, response);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ForwardNonUTF8Servlet extends HttpServlet implements Servlet
|
||||
{
|
||||
@Override
|
||||
|
@ -734,7 +789,7 @@ public class DispatcherTest
|
|||
assertEquals("do=assertforward&do=more&test=1", request.getAttribute(Dispatcher.FORWARD_QUERY_STRING));
|
||||
HttpServletMapping fwdMapping = (HttpServletMapping)request.getAttribute(Dispatcher.FORWARD_MAPPING);
|
||||
assertNotNull(fwdMapping);
|
||||
assertEquals("/ForwardServlet", fwdMapping.getMatchValue());
|
||||
assertEquals("ForwardServlet", fwdMapping.getMatchValue());
|
||||
|
||||
List<String> expectedAttributeNames = Arrays.asList(Dispatcher.FORWARD_REQUEST_URI, Dispatcher.FORWARD_CONTEXT_PATH,
|
||||
Dispatcher.FORWARD_SERVLET_PATH, Dispatcher.FORWARD_QUERY_STRING, Dispatcher.FORWARD_MAPPING);
|
||||
|
@ -769,7 +824,7 @@ public class DispatcherTest
|
|||
assertEquals("do=assertforward&foreign=%d2%e5%ec%ef%e5%f0%e0%f2%f3%f0%e0&test=1", request.getAttribute(Dispatcher.FORWARD_QUERY_STRING));
|
||||
HttpServletMapping fwdMapping = (HttpServletMapping)request.getAttribute(Dispatcher.FORWARD_MAPPING);
|
||||
assertNotNull(fwdMapping);
|
||||
assertEquals("/ForwardServlet", fwdMapping.getMatchValue());
|
||||
assertEquals("ForwardServlet", fwdMapping.getMatchValue());
|
||||
|
||||
List<String> expectedAttributeNames = Arrays.asList(Dispatcher.FORWARD_REQUEST_URI, Dispatcher.FORWARD_CONTEXT_PATH,
|
||||
Dispatcher.FORWARD_SERVLET_PATH, Dispatcher.FORWARD_QUERY_STRING, Dispatcher.FORWARD_MAPPING);
|
||||
|
@ -818,7 +873,7 @@ public class DispatcherTest
|
|||
assertEquals("do=end&do=the", request.getAttribute(Dispatcher.INCLUDE_QUERY_STRING));
|
||||
HttpServletMapping incMapping = (HttpServletMapping)request.getAttribute(Dispatcher.INCLUDE_MAPPING);
|
||||
assertNotNull(incMapping);
|
||||
assertEquals("/AssertIncludeServlet", incMapping.getMatchValue());
|
||||
assertEquals("AssertIncludeServlet", incMapping.getMatchValue());
|
||||
|
||||
List expectedAttributeNames = Arrays.asList(Dispatcher.INCLUDE_REQUEST_URI, Dispatcher.INCLUDE_CONTEXT_PATH,
|
||||
Dispatcher.INCLUDE_SERVLET_PATH, Dispatcher.INCLUDE_QUERY_STRING, Dispatcher.INCLUDE_MAPPING);
|
||||
|
@ -851,7 +906,7 @@ public class DispatcherTest
|
|||
assertEquals("do=include", request.getAttribute(Dispatcher.FORWARD_QUERY_STRING));
|
||||
HttpServletMapping fwdMapping = (HttpServletMapping)request.getAttribute(Dispatcher.FORWARD_MAPPING);
|
||||
assertNotNull(fwdMapping);
|
||||
assertEquals("/ForwardServlet", fwdMapping.getMatchValue());
|
||||
assertEquals("ForwardServlet", fwdMapping.getMatchValue());
|
||||
|
||||
assertEquals("/context/AssertForwardIncludeServlet/assertpath", request.getAttribute(Dispatcher.INCLUDE_REQUEST_URI));
|
||||
assertEquals("/context", request.getAttribute(Dispatcher.INCLUDE_CONTEXT_PATH));
|
||||
|
@ -860,7 +915,7 @@ public class DispatcherTest
|
|||
assertEquals("do=end", request.getAttribute(Dispatcher.INCLUDE_QUERY_STRING));
|
||||
HttpServletMapping incMapping = (HttpServletMapping)request.getAttribute(Dispatcher.INCLUDE_MAPPING);
|
||||
assertNotNull(incMapping);
|
||||
assertEquals("/AssertForwardIncludeServlet", incMapping.getMatchValue());
|
||||
assertEquals("AssertForwardIncludeServlet", incMapping.getMatchValue());
|
||||
|
||||
List expectedAttributeNames = Arrays.asList(Dispatcher.FORWARD_REQUEST_URI, Dispatcher.FORWARD_CONTEXT_PATH, Dispatcher.FORWARD_SERVLET_PATH,
|
||||
Dispatcher.FORWARD_PATH_INFO, Dispatcher.FORWARD_QUERY_STRING, Dispatcher.FORWARD_MAPPING,
|
||||
|
@ -902,7 +957,7 @@ public class DispatcherTest
|
|||
assertEquals("do=forward", request.getAttribute(Dispatcher.FORWARD_QUERY_STRING));
|
||||
HttpServletMapping fwdMapping = (HttpServletMapping)request.getAttribute(Dispatcher.FORWARD_MAPPING);
|
||||
assertNotNull(fwdMapping);
|
||||
assertEquals("/IncludeServlet", fwdMapping.getMatchValue());
|
||||
assertEquals("IncludeServlet", fwdMapping.getMatchValue());
|
||||
|
||||
List expectedAttributeNames = Arrays.asList(Dispatcher.FORWARD_REQUEST_URI, Dispatcher.FORWARD_CONTEXT_PATH, Dispatcher.FORWARD_SERVLET_PATH,
|
||||
Dispatcher.FORWARD_PATH_INFO, Dispatcher.FORWARD_QUERY_STRING, Dispatcher.FORWARD_MAPPING);
|
||||
|
|
|
@ -62,7 +62,6 @@ import javax.servlet.http.HttpSessionEvent;
|
|||
import javax.servlet.http.HttpSessionIdListener;
|
||||
import javax.servlet.http.HttpSessionListener;
|
||||
|
||||
import org.eclipse.jetty.http.pathmap.MappedResource;
|
||||
import org.eclipse.jetty.logging.StacklessLogging;
|
||||
import org.eclipse.jetty.security.ConstraintSecurityHandler;
|
||||
import org.eclipse.jetty.security.RoleInfo;
|
||||
|
@ -1376,9 +1375,9 @@ public class ServletContextHandlerTest
|
|||
|
||||
root.addBean(new MySCIStarter(root.getServletContext(), new JSPAddingSCI()), true);
|
||||
_server.start();
|
||||
MappedResource<ServletHolder> mappedServlet = root.getServletHandler().getMappedServlet("/somejsp/xxx");
|
||||
assertNotNull(mappedServlet.getResource());
|
||||
assertEquals("some.jsp", mappedServlet.getResource().getName());
|
||||
ServletHandler.MappedServlet mappedServlet = root.getServletHandler().getMappedServlet("/somejsp/xxx");
|
||||
assertNotNull(mappedServlet.getServletHolder());
|
||||
assertEquals("some.jsp", mappedServlet.getServletHolder().getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -1452,9 +1451,9 @@ public class ServletContextHandlerTest
|
|||
|
||||
root.addBean(new MySCIStarter(root.getServletContext(), new JSPAddingSCI()), true);
|
||||
_server.start();
|
||||
MappedResource<ServletHolder> mappedServlet = root.getServletHandler().getMappedServlet("/bar/xxx");
|
||||
assertNotNull(mappedServlet.getResource());
|
||||
assertEquals("some.jsp", mappedServlet.getResource().getName());
|
||||
ServletHandler.MappedServlet mappedServlet = root.getServletHandler().getMappedServlet("/bar/xxx");
|
||||
assertNotNull(mappedServlet.getServletHolder());
|
||||
assertEquals("some.jsp", mappedServlet.getServletHolder().getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -21,7 +21,6 @@ package org.eclipse.jetty.servlet;
|
|||
import java.util.EnumSet;
|
||||
import javax.servlet.DispatcherType;
|
||||
|
||||
import org.eclipse.jetty.http.pathmap.MappedResource;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
@ -79,17 +78,17 @@ public class ServletHandlerTest
|
|||
fm5.setFilterHolder(fh5);
|
||||
|
||||
sh1.setName("s1");
|
||||
sm1.setDefault(false);
|
||||
sm1.setFromDefaultDescriptor(false);
|
||||
sm1.setPathSpec("/foo/*");
|
||||
sm1.setServletName("s1");
|
||||
|
||||
sh2.setName("s2");
|
||||
sm2.setDefault(false);
|
||||
sm2.setFromDefaultDescriptor(false);
|
||||
sm2.setPathSpec("/foo/*");
|
||||
sm2.setServletName("s2");
|
||||
|
||||
sh3.setName("s3");
|
||||
sm3.setDefault(true);
|
||||
sm3.setFromDefaultDescriptor(true);
|
||||
sm3.setPathSpec("/foo/*");
|
||||
sm3.setServletName("s3");
|
||||
}
|
||||
|
@ -251,9 +250,9 @@ public class ServletHandlerTest
|
|||
|
||||
handler.updateMappings();
|
||||
|
||||
MappedResource<ServletHolder> entry = handler.getMappedServlet("/foo/*");
|
||||
ServletHandler.MappedServlet entry = handler.getMappedServlet("/foo/*");
|
||||
assertNotNull(entry);
|
||||
assertEquals("s1", entry.getResource().getName());
|
||||
assertEquals("s1", entry.getServletHolder().getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -292,9 +291,9 @@ public class ServletHandlerTest
|
|||
handler.addServletMapping(sm2);
|
||||
handler.updateMappings();
|
||||
|
||||
MappedResource<ServletHolder> entry = handler.getMappedServlet("/foo/*");
|
||||
ServletHandler.MappedServlet entry = handler.getMappedServlet("/foo/*");
|
||||
assertNotNull(entry);
|
||||
assertEquals("s2", entry.getResource().getName());
|
||||
assertEquals("s2", entry.getServletHolder().getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -1200,7 +1200,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
|
|||
{
|
||||
ServletMapping mapping = new ServletMapping(new Source(Source.Origin.DESCRIPTOR, descriptor.getResource().toString()));
|
||||
mapping.setServletName(servletName);
|
||||
mapping.setDefault(descriptor instanceof DefaultsDescriptor);
|
||||
mapping.setFromDefaultDescriptor(descriptor instanceof DefaultsDescriptor);
|
||||
|
||||
List<String> paths = new ArrayList<String>();
|
||||
Iterator<XmlParser.Node> iter = node.iterator("url-pattern");
|
||||
|
@ -1221,9 +1221,9 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
|
|||
{
|
||||
//The same path has been mapped multiple times, either to a different servlet or the same servlet.
|
||||
//If its a different servlet, this is only valid to do if the old mapping was from a default descriptor.
|
||||
if (p.equals(ps) && (sm.isDefault() || servletName.equals(sm.getServletName())))
|
||||
if (p.equals(ps) && (sm.isFromDefaultDescriptor() || servletName.equals(sm.getServletName())))
|
||||
{
|
||||
if (sm.isDefault())
|
||||
if (sm.isFromDefaultDescriptor())
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("{} in mapping {} from defaults descriptor is overridden by ", ps, sm, servletName);
|
||||
|
|
Loading…
Reference in New Issue