String old_servlet_path=null;
String old_path_info=null;
ClassLoader old_classloader=null;
Thread current_thread=null;
Request base_request=(request instanceof Request)?(Request)request:HttpConnection.getCurrentConnection().getRequest();
if( !isStarted() || _shutdown || (dispatch==REQUEST && base_request.isHandled()))
return;
old_context=base_request.getContext();
// Are we already in this context?
if (old_context!=_scontext)
{
new_context=true;
// Check the vhosts
if (_vhosts!=null && _vhosts.length>0)
{
String vhost = normalizeHostname( request.getServerName());
boolean match=false;
// TODO non-linear lookup
for (int i=0;!match && i<_vhosts.length;i++)
{
String contextVhost = _vhosts[i];
if(contextVhost==null) continue;
if(contextVhost.startsWith("*.")) {
// wildcard only at the beginning, and only for one additional subdomain level
match=contextVhost.regionMatches(true,2,vhost,vhost.indexOf(".")+1,contextVhost.length()-2);
} else
match=contextVhost.equalsIgnoreCase(vhost);
}
if (!match)
return;
}
// Check the connector
if (_connectors!=null && _connectors.size()>0)
{
String connector=HttpConnection.getCurrentConnection().getConnector().getName();
if (connector==null || !_connectors.contains(connector))
return;
}
// Nope - so check the target.
if (dispatch==REQUEST)
{
if (_compactPath)
target=URIUtil.compactPath(target);
if (target.equals(_contextPath))
{
if (!_allowNullPathInfo && !target.endsWith(URIUtil.SLASH))
{
base_request.setHandled(true);
if (request.getQueryString()!=null)
response.sendRedirect(URIUtil.addPaths(request.getRequestURI(),URIUtil.SLASH)+"?"+request.getQueryString());
else
response.sendRedirect(URIUtil.addPaths(request.getRequestURI(),URIUtil.SLASH));
return;
}
if (_contextPath.length()>1)
{
target=URIUtil.SLASH;
request.setAttribute("org.mortbay.jetty.nullPathInfo",target);
}
}
else if (target.startsWith(_contextPath) && (_contextPath.length()==1 || target.charAt(_contextPath.length())=='/'))
{
if (_contextPath.length()>1)
target=target.substring(_contextPath.length());
}
else
{
// Not for this context!
return;
}
}
}
try
{
old_context_path=base_request.getContextPath();
old_servlet_path=base_request.getServletPath();
old_path_info=base_request.getPathInfo();
// Update the paths
base_request.setContext(_scontext);
if (dispatch!=INCLUDE && target.startsWith("/"))
{
if (_contextPath.length()==1)
base_request.setContextPath("");
else
base_request.setContextPath(_contextPath);
base_request.setServletPath(null);
base_request.setPathInfo(target);
}
ServletRequestEvent event=null;
if (new_context)
{
// Set the classloader
if (_classLoader!=null)
{
current_thread=Thread.currentThread();
old_classloader=current_thread.getContextClassLoader();
current_thread.setContextClassLoader(_classLoader);
}
// Handle the REALLY SILLY request events!
base_request.setRequestListeners(_requestListeners);
if (_requestAttributeListeners!=null)
{
final int s=LazyList.size(_requestAttributeListeners);
for(int i=0;i<s;i++)
base_request.addEventListener(((EventListener)LazyList.get(_requestAttributeListeners,i)));
}
}
// Handle the request
try
{
if (dispatch==REQUEST && isProtectedTarget(target))
throw new HttpException(HttpServletResponse.SC_NOT_FOUND);
Handler handler = getHandler();
if (handler!=null)
handler.handle(target, request, response, dispatch);
}
catch(HttpException e)
{
Log.debug(e);
response.sendError(e.getStatus(), e.getReason());
}
finally
{
// Handle more REALLY SILLY request events!
if (new_context)
{
base_request.takeRequestListeners();
if (_requestAttributeListeners!=null)
{
for(int i=LazyList.size(_requestAttributeListeners);i-->0;)
base_request.removeEventListener(((EventListener)LazyList.get(_requestAttributeListeners,i)));
}
}
}
}
finally
{
if (old_context!=_scontext)
{
// reset the classloader
if (_classLoader!=null)
{
current_thread.setContextClassLoader(old_classloader);
}
// reset the context and servlet path.
base_request.setContext(old_context);
base_request.setContextPath(old_context_path);
base_request.setServletPath(old_servlet_path);
base_request.setPathInfo(old_path_info);
}
}
}