Merge remote-tracking branch 'origin/jetty-9.4.x' into jetty-10.0.x
This commit is contained in:
commit
911173f8f7
|
@ -205,7 +205,7 @@ public class Request implements HttpServletRequest
|
|||
private String _pathInContext;
|
||||
private ServletPathMapping _servletPathMapping;
|
||||
private boolean _secure;
|
||||
private String _asyncNotSupportedSource = null;
|
||||
private Object _asyncNotSupportedSource = null;
|
||||
private boolean _newContext;
|
||||
private boolean _cookiesExtracted = false;
|
||||
private boolean _handled = false;
|
||||
|
@ -1845,7 +1845,7 @@ public class Request implements HttpServletRequest
|
|||
_requestAttributeListeners.remove(listener);
|
||||
}
|
||||
|
||||
public void setAsyncSupported(boolean supported, String source)
|
||||
public void setAsyncSupported(boolean supported, Object source)
|
||||
{
|
||||
_asyncNotSupportedSource = supported ? null : (source == null ? "unknown" : source);
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ import javax.servlet.ServletException;
|
|||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.util.TypeUtil;
|
||||
import org.eclipse.jetty.util.component.Dumpable;
|
||||
import org.eclipse.jetty.util.component.DumpableCollection;
|
||||
|
@ -200,11 +201,24 @@ public class FilterHolder extends Holder<Filter>
|
|||
return _filter;
|
||||
}
|
||||
|
||||
public void doFilter(ServletRequest request, ServletResponse response,
|
||||
FilterChain chain)
|
||||
throws IOException, ServletException
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
|
||||
{
|
||||
_filter.doFilter(request, response, chain);
|
||||
if (isAsyncSupported() || !request.isAsyncSupported())
|
||||
getFilter().doFilter(request, response, chain);
|
||||
else
|
||||
{
|
||||
Request baseRequest = Request.getBaseRequest(request);
|
||||
Objects.requireNonNull(baseRequest);
|
||||
try
|
||||
{
|
||||
baseRequest.setAsyncSupported(false, this);
|
||||
getFilter().doFilter(request, response, chain);
|
||||
}
|
||||
finally
|
||||
{
|
||||
baseRequest.setAsyncSupported(true, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -27,10 +27,9 @@ import java.util.EventListener;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Stream;
|
||||
|
@ -62,7 +61,6 @@ import org.eclipse.jetty.server.UserIdentity;
|
|||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.server.handler.ScopedHandler;
|
||||
import org.eclipse.jetty.util.ArrayUtil;
|
||||
import org.eclipse.jetty.util.LazyList;
|
||||
import org.eclipse.jetty.util.MultiException;
|
||||
import org.eclipse.jetty.util.MultiMap;
|
||||
import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
||||
|
@ -99,7 +97,7 @@ public class ServletHandler extends ScopedHandler
|
|||
private int _matchBeforeIndex = -1; //index of last programmatic FilterMapping with isMatchAfter=false
|
||||
private int _matchAfterIndex = -1; //index of 1st programmatic FilterMapping with isMatchAfter=true
|
||||
private boolean _filterChainsCached = true;
|
||||
private int _maxFilterChainsCacheSize = 512;
|
||||
private int _maxFilterChainsCacheSize = 1024;
|
||||
private boolean _startWithUnavailable = false;
|
||||
private boolean _ensureDefaultServlet = true;
|
||||
private IdentityService _identityService;
|
||||
|
@ -110,6 +108,7 @@ public class ServletHandler extends ScopedHandler
|
|||
private final Map<String, FilterHolder> _filterNameMap = new HashMap<>();
|
||||
private List<FilterMapping> _filterPathMappings;
|
||||
private MultiMap<FilterMapping> _filterNameMappings;
|
||||
private List<FilterMapping> _wildFilterNameMappings;
|
||||
|
||||
private final Map<String, MappedServlet> _servletNameMap = new HashMap<>();
|
||||
private PathMappings<MappedServlet> _servletPathMap;
|
||||
|
@ -120,9 +119,6 @@ public class ServletHandler extends ScopedHandler
|
|||
@SuppressWarnings("unchecked")
|
||||
protected final ConcurrentMap<String, FilterChain>[] _chainCache = new ConcurrentMap[FilterMapping.ALL];
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected final Queue<String>[] _chainLRU = new Queue[FilterMapping.ALL];
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
|
@ -138,7 +134,7 @@ public class ServletHandler extends ScopedHandler
|
|||
@Override
|
||||
public boolean isDumpable(Object o)
|
||||
{
|
||||
return !(o instanceof Holder || o instanceof BaseHolder || o instanceof FilterMapping || o instanceof ServletMapping);
|
||||
return !(o instanceof BaseHolder || o instanceof FilterMapping || o instanceof ServletMapping);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -187,12 +183,6 @@ public class ServletHandler extends ScopedHandler
|
|||
_chainCache[FilterMapping.INCLUDE] = new ConcurrentHashMap<>();
|
||||
_chainCache[FilterMapping.ERROR] = new ConcurrentHashMap<>();
|
||||
_chainCache[FilterMapping.ASYNC] = new ConcurrentHashMap<>();
|
||||
|
||||
_chainLRU[FilterMapping.REQUEST] = new ConcurrentLinkedQueue<>();
|
||||
_chainLRU[FilterMapping.FORWARD] = new ConcurrentLinkedQueue<>();
|
||||
_chainLRU[FilterMapping.INCLUDE] = new ConcurrentLinkedQueue<>();
|
||||
_chainLRU[FilterMapping.ERROR] = new ConcurrentLinkedQueue<>();
|
||||
_chainLRU[FilterMapping.ASYNC] = new ConcurrentLinkedQueue<>();
|
||||
}
|
||||
|
||||
if (_contextHandler == null)
|
||||
|
@ -274,14 +264,14 @@ 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);
|
||||
FilterHolder[] fhs = filterHolders.toArray(new FilterHolder[0]);
|
||||
updateBeans(_filters, fhs);
|
||||
_filters = fhs;
|
||||
FilterMapping[] fms = (FilterMapping[])LazyList.toArray(filterMappings, FilterMapping.class);
|
||||
FilterMapping[] fms = filterMappings.toArray(new FilterMapping[0]);
|
||||
updateBeans(_filterMappings, fms);
|
||||
_filterMappings = fms;
|
||||
|
||||
_matchAfterIndex = (_filterMappings == null || _filterMappings.length == 0 ? -1 : _filterMappings.length - 1);
|
||||
_matchAfterIndex = (_filterMappings.length == 0 ? -1 : _filterMappings.length - 1);
|
||||
_matchBeforeIndex = -1;
|
||||
|
||||
// Stop servlets
|
||||
|
@ -314,10 +304,10 @@ 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);
|
||||
ServletHolder[] shs = servletHolders.toArray(new ServletHolder[0]);
|
||||
updateBeans(_servlets, shs);
|
||||
_servlets = shs;
|
||||
ServletMapping[] sms = (ServletMapping[])LazyList.toArray(servletMappings, ServletMapping.class);
|
||||
ServletMapping[] sms = servletMappings.toArray(new ServletMapping[0]);
|
||||
updateBeans(_servletMappings, sms);
|
||||
_servletMappings = sms;
|
||||
|
||||
|
@ -343,7 +333,7 @@ public class ServletHandler extends ScopedHandler
|
|||
listenerHolders.add(listener);
|
||||
}
|
||||
}
|
||||
ListenerHolder[] listeners = (ListenerHolder[])LazyList.toArray(listenerHolders, ListenerHolder.class);
|
||||
ListenerHolder[] listeners = listenerHolders.toArray(new ListenerHolder[0]);
|
||||
updateBeans(_listeners, listeners);
|
||||
_listeners = listeners;
|
||||
|
||||
|
@ -581,85 +571,66 @@ public class ServletHandler extends ScopedHandler
|
|||
return chain;
|
||||
}
|
||||
|
||||
// Build list of filters (list of FilterHolder objects)
|
||||
List<FilterHolder> filters = new ArrayList<>();
|
||||
// Build the filter chain from the inside out.
|
||||
// ie first wrap the servlet with the last filter to be applied.
|
||||
// The mappings lists have been reversed to make this simple and fast.
|
||||
FilterChain chain = null;
|
||||
|
||||
// Path filters
|
||||
if (pathInContext != null && _filterPathMappings != null)
|
||||
{
|
||||
for (FilterMapping filterPathMapping : _filterPathMappings)
|
||||
{
|
||||
if (filterPathMapping.appliesTo(pathInContext, dispatch))
|
||||
filters.add(filterPathMapping.getFilterHolder());
|
||||
}
|
||||
}
|
||||
|
||||
// Servlet name filters
|
||||
if (servletHolder != null && _filterNameMappings != null && !_filterNameMappings.isEmpty())
|
||||
{
|
||||
Object o = _filterNameMappings.get(servletHolder.getName());
|
||||
if (_wildFilterNameMappings != null)
|
||||
for (FilterMapping mapping : _wildFilterNameMappings)
|
||||
chain = newFilterChain(mapping.getFilterHolder(), chain == null ? new ChainEnd(servletHolder) : chain);
|
||||
|
||||
for (int i = 0; i < LazyList.size(o); i++)
|
||||
for (FilterMapping mapping : _filterNameMappings.get(servletHolder.getName()))
|
||||
{
|
||||
FilterMapping mapping = LazyList.get(o, i);
|
||||
if (mapping.appliesTo(dispatch))
|
||||
filters.add(mapping.getFilterHolder());
|
||||
}
|
||||
|
||||
o = _filterNameMappings.get("*");
|
||||
for (int i = 0; i < LazyList.size(o); i++)
|
||||
{
|
||||
FilterMapping mapping = LazyList.get(o, i);
|
||||
if (mapping.appliesTo(dispatch))
|
||||
filters.add(mapping.getFilterHolder());
|
||||
chain = newFilterChain(mapping.getFilterHolder(), chain == null ? new ChainEnd(servletHolder) : chain);
|
||||
}
|
||||
}
|
||||
|
||||
if (filters.isEmpty())
|
||||
return null;
|
||||
if (pathInContext != null && _filterPathMappings != null)
|
||||
{
|
||||
for (FilterMapping mapping : _filterPathMappings)
|
||||
{
|
||||
if (mapping.appliesTo(pathInContext, dispatch))
|
||||
chain = newFilterChain(mapping.getFilterHolder(), chain == null ? new ChainEnd(servletHolder) : chain);
|
||||
}
|
||||
}
|
||||
|
||||
FilterChain chain = null;
|
||||
if (_filterChainsCached)
|
||||
{
|
||||
chain = newCachedChain(filters, servletHolder);
|
||||
|
||||
final Map<String, FilterChain> cache = _chainCache[dispatch];
|
||||
final Queue<String> lru = _chainLRU[dispatch];
|
||||
|
||||
// Do we have too many cached chains?
|
||||
while (_maxFilterChainsCacheSize > 0 && cache.size() >= _maxFilterChainsCacheSize)
|
||||
if (_maxFilterChainsCacheSize > 0 && cache.size() >= _maxFilterChainsCacheSize)
|
||||
{
|
||||
// The LRU list is not atomic with the cache map, so be prepared to invalidate if
|
||||
// a key is not found to delete.
|
||||
// Delete by LRU (where U==created)
|
||||
String k = lru.poll();
|
||||
if (k == null)
|
||||
{
|
||||
cache.clear();
|
||||
break;
|
||||
}
|
||||
cache.remove(k);
|
||||
// flush the cache
|
||||
LOG.debug("{} flushed filter chain cache for {}", this, baseRequest.getDispatcherType());
|
||||
cache.clear();
|
||||
}
|
||||
|
||||
chain = chain == null ? new ChainEnd(servletHolder) : chain;
|
||||
// flush the cache
|
||||
LOG.debug("{} cached filter chain for {}: {}", this, baseRequest.getDispatcherType(), chain);
|
||||
cache.put(key, chain);
|
||||
lru.add(key);
|
||||
}
|
||||
else
|
||||
chain = new Chain(baseRequest, filters, servletHolder);
|
||||
|
||||
return chain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a FilterChain that calls the passed filter with the passed chain
|
||||
* @param filterHolder The filter to invoke
|
||||
* @param chain The chain to pass to the filter
|
||||
* @return A FilterChain that invokes the filter with the chain
|
||||
*/
|
||||
protected FilterChain newFilterChain(FilterHolder filterHolder, FilterChain chain)
|
||||
{
|
||||
return new Chain(filterHolder, chain);
|
||||
}
|
||||
|
||||
protected void invalidateChainsCache()
|
||||
{
|
||||
if (_chainLRU[FilterMapping.REQUEST] != null)
|
||||
if (_chainCache[FilterMapping.REQUEST] != null)
|
||||
{
|
||||
_chainLRU[FilterMapping.REQUEST].clear();
|
||||
_chainLRU[FilterMapping.FORWARD].clear();
|
||||
_chainLRU[FilterMapping.INCLUDE].clear();
|
||||
_chainLRU[FilterMapping.ERROR].clear();
|
||||
_chainLRU[FilterMapping.ASYNC].clear();
|
||||
|
||||
_chainCache[FilterMapping.REQUEST].clear();
|
||||
_chainCache[FilterMapping.FORWARD].clear();
|
||||
_chainCache[FilterMapping.INCLUDE].clear();
|
||||
|
@ -810,18 +781,6 @@ public class ServletHandler extends ScopedHandler
|
|||
return new ListenerHolder(source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new CachedChain
|
||||
*
|
||||
* @param filters the filter chain to be cached as a collection of {@link FilterHolder}
|
||||
* @param servletHolder the servletHolder
|
||||
* @return a new {@link CachedChain} instance
|
||||
*/
|
||||
public CachedChain newCachedChain(List<FilterHolder> filters, ServletHolder servletHolder)
|
||||
{
|
||||
return new CachedChain(filters, servletHolder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new servlet holder
|
||||
*
|
||||
|
@ -872,6 +831,7 @@ public class ServletHandler extends ScopedHandler
|
|||
*/
|
||||
public void addServletWithMapping(ServletHolder servlet, String pathSpec)
|
||||
{
|
||||
Objects.requireNonNull(servlet);
|
||||
ServletHolder[] holders = getServlets();
|
||||
if (holders != null)
|
||||
holders = holders.clone();
|
||||
|
@ -880,7 +840,7 @@ public class ServletHandler extends ScopedHandler
|
|||
{
|
||||
try (AutoLock l = lock())
|
||||
{
|
||||
if (servlet != null && !containsServletHolder(servlet))
|
||||
if (!containsServletHolder(servlet))
|
||||
setServlets(ArrayUtil.addToArray(holders, servlet, ServletHolder.class));
|
||||
}
|
||||
|
||||
|
@ -985,6 +945,7 @@ public class ServletHandler extends ScopedHandler
|
|||
*/
|
||||
public void addFilterWithMapping(FilterHolder holder, String pathSpec, EnumSet<DispatcherType> dispatches)
|
||||
{
|
||||
Objects.requireNonNull(holder);
|
||||
FilterHolder[] holders = getFilters();
|
||||
if (holders != null)
|
||||
holders = holders.clone();
|
||||
|
@ -993,7 +954,7 @@ public class ServletHandler extends ScopedHandler
|
|||
{
|
||||
try (AutoLock l = lock())
|
||||
{
|
||||
if (holder != null && !containsFilterHolder(holder))
|
||||
if (!containsFilterHolder(holder))
|
||||
setFilters(ArrayUtil.addToArray(holders, holder, FilterHolder.class));
|
||||
}
|
||||
|
||||
|
@ -1053,6 +1014,7 @@ public class ServletHandler extends ScopedHandler
|
|||
*/
|
||||
public void addFilterWithMapping(FilterHolder holder, String pathSpec, int dispatches)
|
||||
{
|
||||
Objects.requireNonNull(holder);
|
||||
FilterHolder[] holders = getFilters();
|
||||
if (holders != null)
|
||||
holders = holders.clone();
|
||||
|
@ -1061,7 +1023,7 @@ public class ServletHandler extends ScopedHandler
|
|||
{
|
||||
try (AutoLock l = lock())
|
||||
{
|
||||
if (holder != null && !containsFilterHolder(holder))
|
||||
if (!containsFilterHolder(holder))
|
||||
setFilters(ArrayUtil.addToArray(holders, holder, FilterHolder.class));
|
||||
}
|
||||
|
||||
|
@ -1295,6 +1257,7 @@ public class ServletHandler extends ScopedHandler
|
|||
{
|
||||
_filterPathMappings = null;
|
||||
_filterNameMappings = null;
|
||||
_wildFilterNameMappings = Collections.emptyList();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1319,6 +1282,13 @@ public class ServletHandler extends ScopedHandler
|
|||
}
|
||||
}
|
||||
}
|
||||
// Reverse filter mappings to apply as wrappers last filter wrapped first
|
||||
for (Map.Entry<String, List<FilterMapping>> entry : _filterNameMappings.entrySet())
|
||||
Collections.reverse(entry.getValue());
|
||||
Collections.reverse(_filterPathMappings);
|
||||
_wildFilterNameMappings = _filterNameMappings.get("*");
|
||||
if (_wildFilterNameMappings != null)
|
||||
Collections.reverse(_wildFilterNameMappings);
|
||||
}
|
||||
|
||||
// Map servlet paths to holders
|
||||
|
@ -1547,159 +1517,6 @@ public class ServletHandler extends ScopedHandler
|
|||
}
|
||||
}
|
||||
|
||||
protected class CachedChain implements FilterChain
|
||||
{
|
||||
FilterHolder _filterHolder;
|
||||
CachedChain _next;
|
||||
ServletHolder _servletHolder;
|
||||
|
||||
/**
|
||||
* @param filters list of {@link FilterHolder} objects
|
||||
* @param servletHolder the current {@link ServletHolder}
|
||||
*/
|
||||
protected CachedChain(List<FilterHolder> filters, ServletHolder servletHolder)
|
||||
{
|
||||
if (!filters.isEmpty())
|
||||
{
|
||||
_filterHolder = filters.get(0);
|
||||
filters.remove(0);
|
||||
_next = new CachedChain(filters, servletHolder);
|
||||
}
|
||||
else
|
||||
_servletHolder = servletHolder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response)
|
||||
throws IOException, ServletException
|
||||
{
|
||||
final Request baseRequest = Request.getBaseRequest(request);
|
||||
|
||||
// pass to next filter
|
||||
if (_filterHolder != null)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("call filter {}", _filterHolder);
|
||||
|
||||
//if the request already does not support async, then the setting for the filter
|
||||
//is irrelevant. However if the request supports async but this filter does not
|
||||
//temporarily turn it off for the execution of the filter
|
||||
if (baseRequest.isAsyncSupported() && !_filterHolder.isAsyncSupported())
|
||||
{
|
||||
try
|
||||
{
|
||||
baseRequest.setAsyncSupported(false, _filterHolder.toString());
|
||||
_filterHolder.doFilter(request, response, _next);
|
||||
}
|
||||
finally
|
||||
{
|
||||
baseRequest.setAsyncSupported(true, null);
|
||||
}
|
||||
}
|
||||
else
|
||||
_filterHolder.doFilter(request, response, _next);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Call servlet
|
||||
HttpServletRequest srequest = (HttpServletRequest)request;
|
||||
if (_servletHolder == null)
|
||||
notFound(baseRequest, srequest, (HttpServletResponse)response);
|
||||
else
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("call servlet {}", _servletHolder);
|
||||
_servletHolder.handle(baseRequest, request, response);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
if (_filterHolder != null)
|
||||
return _filterHolder + "->" + _next.toString();
|
||||
if (_servletHolder != null)
|
||||
return _servletHolder.toString();
|
||||
return "null";
|
||||
}
|
||||
}
|
||||
|
||||
private class Chain implements FilterChain
|
||||
{
|
||||
final Request _baseRequest;
|
||||
final List<FilterHolder> _chain;
|
||||
final ServletHolder _servletHolder;
|
||||
int _filter = 0;
|
||||
|
||||
private Chain(Request baseRequest, List<FilterHolder> filters, ServletHolder servletHolder)
|
||||
{
|
||||
_baseRequest = baseRequest;
|
||||
_chain = filters;
|
||||
_servletHolder = servletHolder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response)
|
||||
throws IOException, ServletException
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("doFilter {}", _filter);
|
||||
|
||||
// pass to next filter
|
||||
if (_filter < _chain.size())
|
||||
{
|
||||
FilterHolder holder = _chain.get(_filter++);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("call filter {}", holder);
|
||||
|
||||
//if the request already does not support async, then the setting for the filter
|
||||
//is irrelevant. However if the request supports async but this filter does not
|
||||
//temporarily turn it off for the execution of the filter
|
||||
if (!holder.isAsyncSupported() && _baseRequest.isAsyncSupported())
|
||||
{
|
||||
try
|
||||
{
|
||||
_baseRequest.setAsyncSupported(false, holder.toString());
|
||||
holder.doFilter(request, response, this);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_baseRequest.setAsyncSupported(true, null);
|
||||
}
|
||||
}
|
||||
else
|
||||
holder.doFilter(request, response, this);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Call servlet
|
||||
HttpServletRequest srequest = (HttpServletRequest)request;
|
||||
if (_servletHolder == null)
|
||||
notFound(Request.getBaseRequest(request), srequest, (HttpServletResponse)response);
|
||||
else
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("call servlet {}", _servletHolder);
|
||||
_servletHolder.handle(_baseRequest, request, response);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder b = new StringBuilder();
|
||||
for (FilterHolder f : _chain)
|
||||
{
|
||||
b.append(f.toString());
|
||||
b.append("->");
|
||||
}
|
||||
b.append(_servletHolder);
|
||||
return b.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The maximum entries in a filter chain cache.
|
||||
*/
|
||||
|
@ -1810,4 +1627,52 @@ public class ServletHandler extends ScopedHandler
|
|||
resp.sendError(HttpServletResponse.SC_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
|
||||
static class Chain implements FilterChain
|
||||
{
|
||||
private final FilterHolder _filterHolder;
|
||||
private final FilterChain _filterChain;
|
||||
|
||||
Chain(FilterHolder filter, FilterChain chain)
|
||||
{
|
||||
_filterHolder = filter;
|
||||
_filterChain = chain;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException
|
||||
{
|
||||
_filterHolder.doFilter(request, response, _filterChain);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("Chain@%x(%s)->%s", hashCode(), _filterHolder, _filterChain);
|
||||
}
|
||||
}
|
||||
|
||||
static class ChainEnd implements FilterChain
|
||||
{
|
||||
private final ServletHolder _servletHolder;
|
||||
|
||||
ChainEnd(ServletHolder holder)
|
||||
{
|
||||
_servletHolder = holder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException
|
||||
{
|
||||
Request baseRequest = Request.getBaseRequest(request);
|
||||
Objects.requireNonNull(baseRequest);
|
||||
_servletHolder.handle(baseRequest, request, response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("ChainEnd@%x(%s)", hashCode(), _servletHolder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue