//
// ========================================================================
-// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
+// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
private ServletHolder[] _servlets=new ServletHolder[0];
private ServletMapping[] _servletMappings;
- private Map<String,ServletMapping> _servletPathMappings = new HashMap<String,ServletMapping>();
-
private final Map<String,FilterHolder> _filterNameMap= new HashMap<>();
private List<FilterMapping> _filterPathMappings;
private MultiMap<FilterMapping> _filterNameMappings;
private ListenerHolder[] _listeners=new ListenerHolder[0];
- protected final ConcurrentMap<?, ?> _chainCache[] = new ConcurrentMap[FilterMapping.ALL];
- protected final Queue<?>[] _chainLRU = new Queue[FilterMapping.ALL];
-
+ @SuppressWarnings("unchecked")
+ protected final ConcurrentMap<String, FilterChain> _chainCache[] = new ConcurrentMap[FilterMapping.ALL];
+
+ @SuppressWarnings("unchecked")
+ protected final Queue<String>[] _chainLRU = new Queue[FilterMapping.ALL];
+
/* ------------------------------------------------------------ */
if (getServletMapping("/")==null && _ensureDefaultServlet)
{
- LOG.debug("Adding Default404Servlet to {}",this);
+ if (LOG.isDebugEnabled())
+ LOG.debug("Adding Default404Servlet to {}",this);
addServletWithMapping(Default404Servlet.class,"/");
updateMappings();
getServletMapping("/").setDefault(true);
_filterPathMappings=null;
_filterNameMappings=null;
_servletPathMap=null;
- _servletPathMappings=null;
}
/* ------------------------------------------------------------ */
*/
public ServletMapping getServletMapping(String pathSpec)
{
- if (pathSpec == null || _servletPathMappings == null)
+ if (pathSpec == null || _servletMappings == null)
return null;
- return _servletPathMappings.get(pathSpec);
+ ServletMapping mapping = null;
+ for (int i=0; i<_servletMappings.length && mapping == null; i++)
+ {
+ ServletMapping m = _servletMappings[i];
+ if (m.getPathSpecs() != null)
+ {
+ for (String p:m.getPathSpecs())
+ {
+ if (pathSpec.equals(p))
+ {
+ mapping = m;
+ break;
+ }
+ }
+ }
+ }
+ return mapping;
}
/* ------------------------------------------------------------ */
}
}
- LOG.debug("chain={}",chain);
+ if (LOG.isDebugEnabled())
+ LOG.debug("chain={}",chain);
+
Throwable th=null;
try
{
res = ((ServletResponseHttpWrapper)res).getResponse();
// Do the filter/handling thang
+ servlet_holder.prepare(baseRequest, req, res);
+
if (chain!=null)
chain.doFilter(req, res);
else
if (filters.size() > 0)
chain= new CachedChain(filters, servletHolder);
- final Map<String,FilterChain> cache=(Map<String, FilterChain>)_chainCache[dispatch];
- final Queue<String> lru=(Queue<String>)_chainLRU[dispatch];
-
- // Do we have too many cached chains?
- while (_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);
- }
-
- cache.put(key,chain);
- lru.add(key);
+ 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)
+ {
+ // 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);
+ }
+
+ cache.put(key,chain);
+ lru.add(key);
}
else if (filters.size() > 0)
chain = new Chain(baseRequest,filters, servletHolder);
{
try
{
- /* if (servlet.getClassName() == null && servlet.getForcedPath() != null)
- {
- ServletHolder forced_holder = _servletPathMap.match(servlet.getForcedPath());
- if (forced_holder == null || forced_holder.getClassName() == null)
- {
- mx.add(new IllegalStateException("No forced path servlet for " + servlet.getForcedPath()));
- continue;
- }
- System.err.println("ServletHandler setting forced path classname to "+forced_holder.getClassName()+ " for "+servlet.getForcedPath());
- servlet.setClassName(forced_holder.getClassName());
- }*/
-
servlet.start();
servlet.initialize();
}
//for each path, look at the mappings where it is referenced
//if a mapping is for a servlet that is not enabled, skip it
Set<ServletMapping> mappings = sms.get(pathSpec);
-
-
-
+
ServletMapping finalMapping = null;
for (ServletMapping mapping : mappings)
{
}
_servletPathMap=pm;
- _servletPathMappings=servletPathMappings;
}
// flush filter chain cache
/* ------------------------------------------------------------ */
protected void notFound(Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
- LOG.debug("Not Found {}",request.getRequestURI());
+ if (LOG.isDebugEnabled())
+ LOG.debug("Not Found {}",request.getRequestURI());
if (getHandler()!=null)
nextHandle(URIUtil.addPaths(request.getServletPath(),request.getPathInfo()),baseRequest,request,response);
}
{
updateBeans(_filterMappings,filterMappings);
_filterMappings = filterMappings;
- updateMappings();
+ if (isStarted()) updateMappings();
invalidateChainsCache();
}
{
updateBeans(_servletMappings,servletMappings);
_servletMappings = servletMappings;
- updateMappings();
+ if (isStarted()) updateMappings();
invalidateChainsCache();
}
// pass to next filter
if (_filterHolder!=null)
{
- LOG.debug("call filter {}", _filterHolder);
+ if (LOG.isDebugEnabled())
+ LOG.debug("call filter {}", _filterHolder);
Filter filter= _filterHolder.getFilter();
- if (_filterHolder.isAsyncSupported())
+
+ //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
+ boolean requestAsyncSupported = baseRequest.isAsyncSupported();
+ try
+ {
+ if (!_filterHolder.isAsyncSupported() && requestAsyncSupported)
+ baseRequest.setAsyncSupported(false);
filter.doFilter(request, response, _next);
- else
+ }
+ finally
{
- final boolean suspendable=baseRequest.isAsyncSupported();
- if (suspendable)
- {
- try
- {
- baseRequest.setAsyncSupported(false);
- filter.doFilter(request, response, _next);
- }
- finally
- {
- baseRequest.setAsyncSupported(true);
- }
- }
- else
- filter.doFilter(request, response, _next);
+ baseRequest.setAsyncSupported(requestAsyncSupported);
}
return;
}
LOG.debug("call filter " + holder);
Filter filter= holder.getFilter();
- if (holder.isAsyncSupported() || !_baseRequest.isAsyncSupported())
+ //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
+ boolean requestAsyncSupported = _baseRequest.isAsyncSupported();
+ try
{
+ if (!holder.isAsyncSupported() && requestAsyncSupported)
+ _baseRequest.setAsyncSupported(false);
filter.doFilter(request, response, this);
}
- else
+ finally
{
- try
- {
- _baseRequest.setAsyncSupported(false);
- filter.doFilter(request, response, this);
- }
- finally
- {
- _baseRequest.setAsyncSupported(true);
- }
+ _baseRequest.setAsyncSupported(requestAsyncSupported);
}
-
return;
}
notFound((request instanceof Request)?((Request)request):HttpChannel.getCurrentHttpChannel().getRequest(), srequest, (HttpServletResponse)response);
else
{
- LOG.debug("call servlet {}", _servletHolder);
+ if (LOG.isDebugEnabled())
+ LOG.debug("call servlet {}", _servletHolder);
_servletHolder.handle(_baseRequest,request, response);
}
}