Merge remote-tracking branch 'origin/jetty-10.0.x' into jetty-11.0.x

Signed-off-by: Greg Wilkins <gregw@webtide.com>
This commit is contained in:
Greg Wilkins 2020-05-20 16:09:55 +02:00
commit 4e8aec47e5
20 changed files with 627 additions and 539 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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());
}

View File

@ -28,24 +28,20 @@ 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
@ -58,13 +54,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);
}
@ -74,18 +70,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;
}
@ -95,54 +85,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);
}
}

View File

@ -101,14 +101,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 +140,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 +156,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 +183,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 +247,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 +271,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 +307,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 +321,11 @@ public class Dispatcher implements RequestDispatcher
@Override
public void setAttribute(String key, Object value)
{
if (_named == null && key.startsWith("jakarta.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 +349,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 +372,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 +382,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 +403,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,40 +417,8 @@ public class Dispatcher implements RequestDispatcher
@Override
public void setAttribute(String key, Object value)
{
if (_named == null && key.startsWith("jakarta.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);
else
_attributes.setAttribute(key, value);
if (_servletPathMapping == null && _named == null && INCLUDE_MAPPING.equals(key))
_servletPathMapping = (ServletPathMapping)value;
}
@Override

View File

@ -83,8 +83,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 +191,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 +202,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 +1760,6 @@ public class Request implements HttpServletRequest
_queryParameters = null;
_contentParameters = null;
_parameters = null;
_pathSpec = null;
_contentParamsExtracted = false;
_inputState = INPUT_NONE;
_multiParts = null;
@ -1925,50 +1843,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 +2346,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;
}
}

View File

@ -21,18 +21,24 @@ package org.eclipse.jetty.server;
import java.util.Set;
import jakarta.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()

View File

@ -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 jakarta.servlet.http.HttpServletMapping;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.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 jakarta.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 +
"}";
}
}

View File

@ -48,6 +48,7 @@ import jakarta.servlet.http.HttpServletMapping;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import jakarta.servlet.http.MappingMatch;
import jakarta.servlet.http.Part;
import jakarta.servlet.http.PushBuilder;
import org.eclipse.jetty.http.BadMessageException;
@ -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();

View File

@ -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;

View File

@ -71,7 +71,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 +171,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
{

View File

@ -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
{

View File

@ -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<>();

View File

@ -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;
}

View File

@ -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"));

View File

@ -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);

View File

@ -1376,9 +1376,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 +1452,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

View File

@ -79,17 +79,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 +251,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 +292,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

View File

@ -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);