// ======================================================================== // $Id: ServletHandler.java,v 1.133 2006/03/15 14:43:00 gregwilkins Exp $ // Copyright 199-2004 Mort Bay Consulting Pty. Ltd. // ------------------------------------------------------------------------ // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ======================================================================== package org.browsermob.proxy.jetty.jetty.servlet; import org.apache.commons.logging.Log; import org.browsermob.proxy.jetty.http.*; import org.browsermob.proxy.jetty.log.LogFactory; import org.browsermob.proxy.jetty.util.*; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.MalformedURLException; import java.net.URL; import java.util.*; /* --------------------------------------------------------------------- */ /** Servlet HttpHandler. * This handler maps requests to servlets that implement the * javax.servlet.http.HttpServlet API. * <P> * This handler does not implement the full J2EE features and is intended to * be used when a full web application is not required. Specifically filters * and request wrapping are not supported. * <P> * If a SessionManager is not added to the handler before it is * initialized, then a HashSessionManager with a standard * java.util.Random generator is created. * <P> * @see org.browsermob.proxy.jetty.jetty.servlet.WebApplicationHandler * @version $Id: ServletHandler.java,v 1.133 2006/03/15 14:43:00 gregwilkins Exp $ * @author Greg Wilkins */ public class ServletHandler extends Container implements HttpHandler { private static Log log = LogFactory.getLog(ServletHandler.class); /* ------------------------------------------------------------ */ public static final String __DEFAULT_SERVLET="default"; public static final String __J_S_CONTEXT_TEMPDIR="javax.servlet.context.tempdir"; public static final String __J_S_ERROR_EXCEPTION="javax.servlet.error.exception"; public static final String __J_S_ERROR_EXCEPTION_TYPE="javax.servlet.error.exception_type"; public static final String __J_S_ERROR_MESSAGE="javax.servlet.error.message"; public static final String __J_S_ERROR_REQUEST_URI="javax.servlet.error.request_uri"; public static final String __J_S_ERROR_SERVLET_NAME="javax.servlet.error.servlet_name"; public static final String __J_S_ERROR_STATUS_CODE="javax.servlet.error.status_code"; /* ------------------------------------------------------------ */ private static final boolean __Slosh2Slash=File.separatorChar=='\\'; private static String __AllowString="GET, HEAD, POST, OPTIONS, TRACE"; /* ------------------------------------------------------------ */ private boolean _usingCookies=true; private boolean _autoInitializeServlets=true; private String _name; /* ------------------------------------------------------------ */ protected PathMap _servletMap=new PathMap(); protected Map _nameMap=new HashMap(); protected Map _attributes=new HashMap(3); protected String _formLoginPage; protected String _formErrorPage; protected SessionManager _sessionManager; protected transient Context _context; protected transient ClassLoader _loader; protected transient Log _contextLog; protected transient HttpContext _httpContext; /* ------------------------------------------------------------ */ /** Constructor. */ public ServletHandler() { _context=new Context(); } /* ------------------------------------------------------------ */ public void setName(String name) { _name=name; } /* ------------------------------------------------------------ */ public String getName() { if (_name==null) { _name=this.getClass().getName(); if (!log.isDebugEnabled()) _name=_name.substring(_name.lastIndexOf('.')+1); } return _name; } /* ------------------------------------------------------------ */ public HttpContext getHttpContext() { return _httpContext; } /* ------------------------------------------------------------ */ public void initialize(HttpContext context) { SessionManager sessionManager=getSessionManager(); if (_httpContext!=null&& _httpContext!=context) throw new IllegalStateException("Can't initialize handler for different context"); _httpContext=context; sessionManager.initialize(this); } /* ------------------------------------------------------------ */ public void formAuthInit(String formLoginPage, String formErrorPage) { _formLoginPage=formLoginPage; _formErrorPage=formErrorPage; } /* ------------------------------------------------------------ */ public void setSessionManager(SessionManager sm) { if (isStarted()) throw new IllegalStateException("Started"); int mii=0; boolean setMii=false; if ( _sessionManager!=null) { mii=_sessionManager.getMaxInactiveInterval(); setMii=true; if (getHttpContext()!=null) _sessionManager.initialize(null); removeComponent(_sessionManager); } _sessionManager=sm; if (_sessionManager!=null) { if (getHttpContext()!=null) _sessionManager.initialize(this); if (setMii) _sessionManager.setMaxInactiveInterval(mii); addComponent(_sessionManager); } _sessionManager=sm; } /* ------------------------------------------------------------ */ public SessionManager getSessionManager() { if (_sessionManager==null) { _sessionManager = new HashSessionManager(); addComponent(_sessionManager); } return _sessionManager; } /* ------------------------------------------------------------ */ public ServletContext getServletContext() { return _context; } /* ------------------------------------------------------------ */ public PathMap getServletMap() { return _servletMap; } /* ------------------------------------------------------------ */ public boolean isUsingCookies() { return _usingCookies; } /* ------------------------------------------------------------ */ /** Set the dynamic servlet path. * @deprecated Use org.mortbay.jetty.servlet.Invoker */ public void setDynamicServletPathSpec(String dynamicServletPathSpec) { log.warn("setDynamicServletPathSpec is Deprecated."); } /* ------------------------------------------------------------ */ /** Set dynamic servlet initial parameters. * @deprecated Use org.mortbay.jetty.servlet.Invoker */ public void setDynamicInitParams(Map initParams) { log.warn("setDynamicInitParams is Deprecated."); } /* ------------------------------------------------------------ */ /** Set serving dynamic system servlets. * @deprecated Use org.mortbay.jetty.servlet.Invoker */ public void setServeDynamicSystemServlets(boolean b) { log.warn("setServeDynamicSystemServlets is Deprecated."); } /* ------------------------------------------------------------ */ public ClassLoader getClassLoader() { return _loader; } /* ------------------------------------------------------------ */ /** * @param uc If true, cookies are used for sessions */ public void setUsingCookies(boolean uc) { _usingCookies=uc; } /* ------------------------------------------------------------ */ public ServletHolder newServletHolder(String name, String servletClass, String forcedPath) { if (_nameMap.containsKey(name)) throw new IllegalArgumentException("Named servlet already exists: "+name); ServletHolder holder = new ServletHolder(this,name,servletClass,forcedPath); addServletHolder(holder); return holder; } /* ------------------------------------------------------------ */ public ServletHolder newServletHolder(String name, String servletClass) { return newServletHolder(name,servletClass,null); } /* ------------------------------------------------------------ */ public ServletHolder getServletHolder(String name) { return (ServletHolder)_nameMap.get(name); } /* ------------------------------------------------------------ */ /** * Map a servlet to a pathSpec * @param pathSpec The pathspec to map * @param servletName The name of the servlet, which must have already been added. * @return The servlet holder of the mapped servlet. */ public ServletHolder mapPathToServlet(String pathSpec, String servletName) { ServletHolder holder =(ServletHolder)_nameMap.get(servletName); if (!pathSpec.startsWith("/") && !pathSpec.startsWith("*")) { log.warn("pathSpec should start with '/' or '*' : "+pathSpec); pathSpec="/"+pathSpec; } if (holder==null) throw new IllegalArgumentException("Unknown servlet: "+servletName); _servletMap.put(pathSpec,holder); return holder; } /* ------------------------------------------------------------ */ /** Add a servlet. * @param name The servlet name. * @param pathSpec A path specification to map this servlet to. * @param servletClass The class name of the servlet. * @param forcedPath If non null, the request attribute * javax.servlet.include.servlet_path will be set to this path before * service is called. * @return The ServletHolder for the servlet. */ public ServletHolder addServlet(String name, String pathSpec, String servletClass, String forcedPath) { ServletHolder holder = getServletHolder(name); if (holder==null) holder = newServletHolder(name,servletClass,forcedPath); mapPathToServlet(pathSpec,name); if (isStarted() && !holder.isStarted()) { try{holder.start();} catch(Exception e){log.warn(LogSupport.EXCEPTION,e);} } return holder; } /* ------------------------------------------------------------ */ /** Add a servlet. * @param name The servlet name. * @param pathSpec A path specification to map this servlet to. * @param servletClass The class name of the servlet. * @return The ServletHolder for the servlet. */ public ServletHolder addServlet(String name, String pathSpec, String servletClass) { return addServlet(name,pathSpec,servletClass,null); } /* ------------------------------------------------------------ */ /** * Add a servlet instance to this handler and map it to a pathspec. * @param pathSpec The pathmapping * @param servletClass The class of the servlet * @return The created ServletHolder */ public ServletHolder addServlet(String pathSpec, String servletClass) { return addServlet(servletClass,pathSpec,servletClass,null); } /* ------------------------------------------------------------ */ /** * Register an existing ServletHolder with this handler. * @param holder the ServletHolder to register. */ public void addServletHolder(ServletHolder holder) { ServletHolder existing = (ServletHolder) _nameMap.get(holder.getName()); if (existing==null) _nameMap.put(holder.getName(),holder); else if (existing!=holder) throw new IllegalArgumentException("Holder already exists for name: "+holder.getName()); addComponent(holder); } /* ------------------------------------------------------------ */ public boolean isAutoInitializeServlets() { return _autoInitializeServlets; } /* ------------------------------------------------------------ */ public void setAutoInitializeServlets(boolean b) { _autoInitializeServlets=b; } /* ----------------------------------------------------------------- */ protected synchronized void doStart() throws Exception { if (isStarted()) return; _contextLog = LogFactory.getLog("org.browsermob.proxy.jetty.jetty.context."+getHttpContext().getHttpContextName()); if (_contextLog==null) _contextLog=log; if (_sessionManager!=null) _sessionManager.start(); // Initialize classloader _loader=getHttpContext().getClassLoader(); if (_autoInitializeServlets) initializeServlets(); } /* ------------------------------------------------------------ */ /** Get Servlets. * @return Array of defined servlets */ public ServletHolder[] getServlets() { // Sort and Initialize servlets HashSet holder_set = new HashSet(_nameMap.size()); holder_set.addAll(_nameMap.values()); ServletHolder holders [] = (ServletHolder []) holder_set.toArray(new ServletHolder [holder_set.size()]); java.util.Arrays.sort (holders); return holders; } /* ------------------------------------------------------------ */ /** Initialize load-on-startup servlets. * Called automatically from start if autoInitializeServlet is true. */ public void initializeServlets() throws Exception { MultiException mx = new MultiException(); // Sort and Initialize servlets ServletHolder[] holders = getServlets(); for (int i=0; i<holders.length; i++) { try{holders[i].start();} catch(Exception e) { log.debug(LogSupport.EXCEPTION,e); mx.add(e); } } mx.ifExceptionThrow(); } /* ----------------------------------------------------------------- */ protected synchronized void doStop() throws Exception { // Sort and Initialize servlets ServletHolder[] holders = getServlets(); // Stop servlets for (int i=holders.length; i-->0;) { try { if (holders[i].isStarted()) holders[i].stop(); } catch(Exception e){log.warn(LogSupport.EXCEPTION,e);} } // Stop the session manager _sessionManager.stop(); _attributes.clear(); _loader=null; } /* ------------------------------------------------------------ */ public HttpSession getHttpSession(String id) { return _sessionManager.getHttpSession(id); } /* ------------------------------------------------------------ */ public HttpSession newHttpSession(HttpServletRequest request) { return _sessionManager.newHttpSession(request); } /* ------------------------------------------------------------ */ /** * Set the session timeout interval in seconds. * @param seconds the length of the session timeout interval in seconds. */ public void setSessionInactiveInterval(int seconds) { _sessionManager.setMaxInactiveInterval(seconds); } /* ----------------------------------------------------------------- */ /** Handle request. * @param pathInContext * @param pathParams * @param httpRequest * @param httpResponse * @exception IOException */ public void handle(String pathInContext, String pathParams, HttpRequest httpRequest, HttpResponse httpResponse) throws IOException { if (!isStarted()) return; // Handle TRACE if (HttpRequest.__TRACE.equals(httpRequest.getMethod())) { handleTrace(httpRequest,httpResponse); return; } // Look for existing request/response objects (from enterScope call) ServletHttpRequest request = (ServletHttpRequest) httpRequest.getWrapper(); ServletHttpResponse response = (ServletHttpResponse) httpResponse.getWrapper(); if (request==null) { // Not in ServletHttpContext, but bumble on anyway request = new ServletHttpRequest(this,pathInContext,httpRequest); response = new ServletHttpResponse(request,httpResponse); httpRequest.setWrapper(request); httpResponse.setWrapper(response); } else { request.recycle(this,pathInContext); response.recycle(); } // Look for the servlet Map.Entry servlet=getHolderEntry(pathInContext); ServletHolder servletHolder=servlet==null?null:(ServletHolder)servlet.getValue(); if(log.isDebugEnabled())log.debug("servlet="+servlet); try { // Adjust request paths if (servlet!=null) { String servletPathSpec=(String)servlet.getKey(); request.setServletPaths(PathMap.pathMatch(servletPathSpec,pathInContext), PathMap.pathInfo(servletPathSpec,pathInContext), servletHolder); } // Handle the session ID request.setRequestedSessionId(pathParams); HttpSession session=request.getSession(false); if (session!=null) ((SessionManager.Session)session).access(); if(log.isDebugEnabled())log.debug("session="+session); // Do that funky filter and servlet thang! if (servletHolder!=null) dispatch(pathInContext,request,response,servletHolder, Dispatcher.__REQUEST); } catch(Exception e) { log.debug(LogSupport.EXCEPTION,e); Throwable th=e; while (th instanceof ServletException) { log.warn(LogSupport.EXCEPTION, th); Throwable cause=((ServletException)th).getRootCause(); if (cause==th || cause==null) break; th=cause; } if (th instanceof HttpException) throw (HttpException)th; if (th instanceof EOFException) throw (IOException)th; else if (log.isDebugEnabled() || !( th instanceof java.io.IOException)) { if (_contextLog!=null) { if (th instanceof RuntimeException) _contextLog.error(httpRequest.getURI()+": ",th); else _contextLog.warn(httpRequest.getURI()+": ",th); } if(log.isDebugEnabled()) { if (th instanceof RuntimeException) log.error(httpRequest.getURI()+": ",th); else log.warn(httpRequest.getURI()+": ",th); log.debug(httpRequest); } } httpResponse.getHttpConnection().forceClose(); if (!httpResponse.isCommitted()) { request.setAttribute(ServletHandler.__J_S_ERROR_EXCEPTION_TYPE,th.getClass()); request.setAttribute(ServletHandler.__J_S_ERROR_EXCEPTION,th); if (th instanceof UnavailableException) { UnavailableException ue = (UnavailableException)th; if (ue.isPermanent()) response.sendError(HttpResponse.__404_Not_Found,e.getMessage()); else response.sendError(HttpResponse.__503_Service_Unavailable,e.getMessage()); } else response.sendError(HttpResponse.__500_Internal_Server_Error,e.getMessage()); } else if(log.isDebugEnabled())log.debug("Response already committed for handling "+th); } catch(Error e) { log.warn("Error for "+httpRequest.getURI(),e); if(log.isDebugEnabled())log.debug(httpRequest); httpResponse.getHttpConnection().forceClose(); if (!httpResponse.isCommitted()) { request.setAttribute(ServletHandler.__J_S_ERROR_EXCEPTION_TYPE,e.getClass()); request.setAttribute(ServletHandler.__J_S_ERROR_EXCEPTION,e); response.sendError(HttpResponse.__500_Internal_Server_Error, e.getMessage()); } else if(log.isDebugEnabled())log.debug("Response already committed for handling ",e); } finally { if (servletHolder!=null && response!=null) { response.complete(); } } } /* ------------------------------------------------------------ */ /** Dispatch to a servletHolder. * This method may be specialized to insert extra handling in the * dispatch of a request to a specific servlet. This is used by * WebApplicatonHandler to implement dispatched filters. * The default implementation simply calls * ServletHolder.handle(request,response) * @param pathInContext The path used to select the servlet holder. * @param request * @param response * @param servletHolder * @param type the type of dispatch as defined in the Dispatcher class. * @exception ServletException * @exception UnavailableException * @exception IOException */ protected void dispatch(String pathInContext, HttpServletRequest request, HttpServletResponse response, ServletHolder servletHolder, int type) throws ServletException, UnavailableException, IOException { servletHolder.handle(request,response); } /* ------------------------------------------------------------ */ /** ServletHolder matching path. * @param pathInContext Path within context. * @return PathMap Entries pathspec to ServletHolder */ public Map.Entry getHolderEntry(String pathInContext) { return _servletMap.getMatch(pathInContext); } /* ------------------------------------------------------------ */ public Set getResourcePaths(String uriInContext) { try { uriInContext=URI.canonicalPath(uriInContext); if (uriInContext==null) return Collections.EMPTY_SET; Resource resource=getHttpContext().getResource(uriInContext); if (resource==null || !resource.isDirectory()) return Collections.EMPTY_SET; String[] contents=resource.list(); if (contents==null || contents.length==0) return Collections.EMPTY_SET; HashSet set = new HashSet(contents.length*2); for (int i=0;i<contents.length;i++) set.add(URI.addPaths(uriInContext,contents[i])); return set; } catch(Exception e) { e.printStackTrace(); LogSupport.ignore(log,e); } return Collections.EMPTY_SET; } /* ------------------------------------------------------------ */ /** Get a Resource. * If no resource is found, resource aliases are tried. * @param uriInContext * @return URL of the resource. * @exception MalformedURLException */ public URL getResource(String uriInContext) throws MalformedURLException { if (uriInContext==null || !uriInContext.startsWith("/")) throw new MalformedURLException(uriInContext); try{ Resource resource = getHttpContext().getResource(uriInContext); if (resource!=null && resource.exists()) return resource.getURL(); } catch(IllegalArgumentException e) { LogSupport.ignore(log,e); } catch(MalformedURLException e) { throw e; } catch(IOException e) { log.warn(LogSupport.EXCEPTION,e); } return null; } /* ------------------------------------------------------------ */ public InputStream getResourceAsStream(String uriInContext) { if (uriInContext==null || !uriInContext.startsWith("/")) return null; try { Resource resource = getHttpContext().getResource(uriInContext); if (resource!=null) return resource.getInputStream(); uriInContext=URI.canonicalPath(uriInContext); URL url = getResource(uriInContext); if (url!=null) return url.openStream(); } catch(IOException e) {LogSupport.ignore(log,e);} return null; } /* ------------------------------------------------------------ */ public String getRealPath(String path) { if(log.isDebugEnabled())log.debug("getRealPath of "+path+" in "+this); if (__Slosh2Slash) path=path.replace('\\','/'); path=URI.canonicalPath(path); if (path==null) return null; Resource baseResource=getHttpContext().getBaseResource(); if (baseResource==null ) return null; try{ Resource resource = baseResource.addPath(path); File file = resource.getFile(); return (file==null)?null:(file.getAbsolutePath()); } catch(IOException e) { log.warn(LogSupport.EXCEPTION,e); return null; } } /* ------------------------------------------------------------ */ public RequestDispatcher getRequestDispatcher(String uriInContext) { if (uriInContext == null) return null; if (!uriInContext.startsWith("/")) return null; try { String query=null; int q=0; if ((q=uriInContext.indexOf('?'))>0) { query=uriInContext.substring(q+1); uriInContext=uriInContext.substring(0,q); } if ((q=uriInContext.indexOf(';'))>0) uriInContext=uriInContext.substring(0,q); String pathInContext=URI.canonicalPath(URI.decodePath(uriInContext)); Map.Entry entry=getHolderEntry(pathInContext); if (entry!=null) return new Dispatcher(ServletHandler.this, uriInContext, pathInContext, query, entry); } catch(Exception e) { LogSupport.ignore(log,e); } return null; } /* ------------------------------------------------------------ */ /** Get Named dispatcher. * @param name The name of the servlet. If null or empty string, the * containers default servlet is returned. * @return Request dispatcher for the named servlet. */ public RequestDispatcher getNamedDispatcher(String name) { if (name == null || name.length()==0) name=__DEFAULT_SERVLET; try { return new Dispatcher(ServletHandler.this,name); } catch(Exception e) {LogSupport.ignore(log,e);} return null; } /* ------------------------------------------------------------ */ protected void notFound(HttpServletRequest request, HttpServletResponse response) throws IOException { if(log.isDebugEnabled())log.debug("Not Found "+request.getRequestURI()); String method=request.getMethod(); // Not found special requests. if (method.equals(HttpRequest.__GET) || method.equals(HttpRequest.__HEAD) || method.equals(HttpRequest.__POST)) { response.sendError(HttpResponse.__404_Not_Found); } else if (method.equals(HttpRequest.__TRACE)) handleTrace(request,response); else if (method.equals(HttpRequest.__OPTIONS)) handleOptions(request,response); else { // Unknown METHOD response.setHeader(HttpFields.__Allow,__AllowString); response.sendError(HttpResponse.__405_Method_Not_Allowed); } } /* ------------------------------------------------------------ */ protected void handleTrace(HttpServletRequest request, HttpServletResponse response) throws IOException { response.setHeader(HttpFields.__ContentType, HttpFields.__MessageHttp); OutputStream out = response.getOutputStream(); ByteArrayISO8859Writer writer = new ByteArrayISO8859Writer(); writer.write(request.toString()); writer.flush(); response.setIntHeader(HttpFields.__ContentLength,writer.size()); writer.writeTo(out); out.flush(); } /* ------------------------------------------------------------ */ protected void handleOptions(HttpServletRequest request, HttpServletResponse response) throws IOException { // Handle OPTIONS request for entire server if ("*".equals(request.getRequestURI())) { // 9.2 response.setIntHeader(HttpFields.__ContentLength,0); response.setHeader(HttpFields.__Allow,__AllowString); response.flushBuffer(); } else response.sendError(HttpResponse.__404_Not_Found); } /* ------------------------------------------------------------ */ public String getErrorPage(int status,ServletHttpRequest request) { return null; } /* ------------------------------------------------------------ */ /** Get context attribute. * Tries ServletHandler attributes and then delegated to HttpContext. * @param name attribute name. * @return attribute */ protected Object getContextAttribute(String name) { if (ServletHandler.__J_S_CONTEXT_TEMPDIR.equals(name)) { // Initialize temporary directory Object t = getHttpContext().getAttribute(ServletHandler.__J_S_CONTEXT_TEMPDIR); if (t instanceof File) return (File)t; return getHttpContext().getTempDirectory(); } if (_attributes.containsKey(name)) return _attributes.get(name); return getHttpContext().getAttribute(name); } /* ------------------------------------------------------------ */ /** Get context attribute names. * Combines ServletHandler and HttpContext attributes. */ protected Enumeration getContextAttributeNames() { if (_attributes.size()==0) return getHttpContext().getAttributeNames(); HashSet set=new HashSet(_attributes.keySet()); Enumeration e=getHttpContext().getAttributeNames(); while(e.hasMoreElements()) set.add(e.nextElement()); return Collections.enumeration(set); } /* ------------------------------------------------------------ */ /* Set a Servlet context attribute. * Servlet Context attributes may hide HttpContext attributes. */ protected void setContextAttribute(String name, Object value) { _attributes.put(name,value); } /* ------------------------------------------------------------ */ /* Remove a Servlet context attribute. * Servlet Context attributes may hide HttpContext attributes. */ protected void removeContextAttribute(String name) { _attributes.remove(name); } /* ----------------------------------------------------------------- */ public void handleTrace(HttpRequest request, HttpResponse response) throws IOException { boolean trace=getHttpContext().getHttpServer().getTrace(); // Handle TRACE by returning request header response.setField(HttpFields.__ContentType, HttpFields.__MessageHttp); if (trace) { OutputStream out = response.getOutputStream(); ByteArrayISO8859Writer writer = new ByteArrayISO8859Writer(); writer.write(request.toString()); writer.flush(); response.setIntField(HttpFields.__ContentLength,writer.size()); writer.writeTo(out); out.flush(); } request.setHandled(true); } /* ----------------------------------------------------------------- */ public void destroy() { Iterator iter = _nameMap.values().iterator(); while (iter.hasNext()) { Object sh=iter.next(); iter.remove(); removeComponent(sh); } if (_sessionManager!=null) removeComponent(_sessionManager); _sessionManager=null; _context=null; super.destroy(); } /* ----------------------------------------------------------------- */ protected void finalize() throws Throwable { destroy(); } /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ class Context implements ServletContext { @Override public String getContextPath() { return null; } /* -------------------------------------------------------- */ ServletHandler getServletHandler() { return ServletHandler.this; } /* -------------------------------------------------------- */ public ServletContext getContext(String uri) { ServletHandler handler= (ServletHandler) getHttpContext().getHttpServer() .findHandler(org.browsermob.proxy.jetty.jetty.servlet.ServletHandler.class, uri, getHttpContext().getVirtualHosts()); if (handler!=null) return handler.getServletContext(); return null; } /* ------------------------------------------------------------ */ public int getMajorVersion() { return 2; } /* ------------------------------------------------------------ */ public int getMinorVersion() { return 4; } /* ------------------------------------------------------------ */ public String getMimeType(String file) { return getHttpContext().getMimeByExtension(file); } /* ------------------------------------------------------------ */ public Set getResourcePaths(String uriInContext) { return ServletHandler.this.getResourcePaths(uriInContext); } /* ------------------------------------------------------------ */ public URL getResource(String uriInContext) throws MalformedURLException { return ServletHandler.this.getResource(uriInContext); } /* ------------------------------------------------------------ */ public InputStream getResourceAsStream(String uriInContext) { return ServletHandler.this.getResourceAsStream(uriInContext); } /* ------------------------------------------------------------ */ public String getRealPath(String path) { return ServletHandler.this.getRealPath(path); } /* ------------------------------------------------------------ */ public RequestDispatcher getRequestDispatcher(String uriInContext) { return ServletHandler.this.getRequestDispatcher(uriInContext); } /* ------------------------------------------------------------ */ public RequestDispatcher getNamedDispatcher(String name) { return ServletHandler.this.getNamedDispatcher(name); } /* ------------------------------------------------------------ */ /** * @deprecated */ public Servlet getServlet(String name) { return null; } /* ------------------------------------------------------------ */ /** * @deprecated */ public Enumeration getServlets() { return Collections.enumeration(Collections.EMPTY_LIST); } /* ------------------------------------------------------------ */ /** * @deprecated */ public Enumeration getServletNames() { return Collections.enumeration(Collections.EMPTY_LIST); } /* ------------------------------------------------------------ */ /** Servlet Log. * Log message to servlet log. Use either the system log or a * LogSinkset via the context attribute * org.mortbay.jetty.servlet.Context.LogSink * @param msg */ public void log(String msg) { _contextLog.info(msg); } /* ------------------------------------------------------------ */ /** * @deprecated As of Java Servlet API 2.1, use * {@link #log(String message, Throwable throwable)} * instead. */ public void log(Exception e, String msg) { _contextLog.warn(msg,e); } /* ------------------------------------------------------------ */ public void log(String msg, Throwable th) { _contextLog.warn(msg,th); } /* ------------------------------------------------------------ */ public String getServerInfo() { return Version.getImplVersion(); } /* ------------------------------------------------------------ */ /** Get context init parameter. * Delegated to HttpContext. * @param param param name * @return param value or null */ public String getInitParameter(String param) { return getHttpContext().getInitParameter(param); } /* ------------------------------------------------------------ */ /** Get context init parameter names. * Delegated to HttpContext. * @return Enumeration of names */ public Enumeration getInitParameterNames() { return getHttpContext().getInitParameterNames(); } /* ------------------------------------------------------------ */ /** Get context attribute. * Tries ServletHandler attributes and then delegated to HttpContext. * @param name attribute name. * @return attribute */ public Object getAttribute(String name) { return getContextAttribute(name); } /* ------------------------------------------------------------ */ /** Get context attribute names. * Combines ServletHandler and HttpContext attributes. */ public Enumeration getAttributeNames() { return getContextAttributeNames(); } /* ------------------------------------------------------------ */ /** Set context attribute names. * Sets the ServletHandler attributes and may hide HttpContext attributes. * @param name attribute name. * @param value attribute value */ public void setAttribute(String name, Object value) { setContextAttribute(name, value); } /* ------------------------------------------------------------ */ /** Remove context attribute. * Puts a null into the ServletHandler attributes and may hide a HttpContext attribute. * @param name attribute name. */ public void removeAttribute(String name) { removeContextAttribute(name); } /* ------------------------------------------------------------ */ public String getServletContextName() { if (getHttpContext() instanceof WebApplicationContext) return ((WebApplicationContext)getHttpContext()).getDisplayName(); return null; } /* ------------------------------------------------------------ */ public String toString() { return "ServletContext["+getHttpContext()+"]"; } } }