X-Git-Url: https://code.wpia.club/?p=gigi.git;a=blobdiff_plain;f=lib%2Fjetty%2Forg%2Feclipse%2Fjetty%2Fservlet%2FInvoker.java;fp=lib%2Fjetty%2Forg%2Feclipse%2Fjetty%2Fservlet%2FInvoker.java;h=4613144bafd48f4df20b6236e02583e5777df0cc;hp=0000000000000000000000000000000000000000;hb=73ef54a38e3930a1a789cdc6b5fa23cdd4c9d086;hpb=515007c7c1351045420669d65b59c08fa46850f2 diff --git a/lib/jetty/org/eclipse/jetty/servlet/Invoker.java b/lib/jetty/org/eclipse/jetty/servlet/Invoker.java new file mode 100644 index 00000000..4613144b --- /dev/null +++ b/lib/jetty/org/eclipse/jetty/servlet/Invoker.java @@ -0,0 +1,314 @@ +// +// ======================================================================== +// Copyright (c) 1995-2014 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 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.servlet; + +import java.io.IOException; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.UnavailableException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import javax.servlet.http.HttpServletResponse; + +import org.eclipse.jetty.server.Dispatcher; +import org.eclipse.jetty.server.Handler; +import org.eclipse.jetty.server.HttpChannel; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.handler.ContextHandler; +import org.eclipse.jetty.server.handler.HandlerWrapper; +import org.eclipse.jetty.util.ArrayUtil; +import org.eclipse.jetty.util.URIUtil; +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; + +/* ------------------------------------------------------------ */ +/** Dynamic Servlet Invoker. + * This servlet invokes anonymous servlets that have not been defined + * in the web.xml or by other means. The first element of the pathInfo + * of a request passed to the envoker is treated as a servlet name for + * an existing servlet, or as a class name of a new servlet. + * This servlet is normally mapped to /servlet/* + * This servlet support the following initParams: + *
+ *  nonContextServlets       If false, the invoker can only load
+ *                           servlets from the contexts classloader.
+ *                           This is false by default and setting this
+ *                           to true may have security implications.
+ *
+ *  verbose                  If true, log dynamic loads
+ *
+ *  *                        All other parameters are copied to the
+ *                           each dynamic servlet as init parameters
+ * 
+ * @version $Id: Invoker.java 4780 2009-03-17 15:36:08Z jesse $ + * + */ +public class Invoker extends HttpServlet +{ + private static final Logger LOG = Log.getLogger(Invoker.class); + + + private ContextHandler _contextHandler; + private ServletHandler _servletHandler; + private Map.Entry _invokerEntry; + private Map _parameters; + private boolean _nonContextServlets; + private boolean _verbose; + + /* ------------------------------------------------------------ */ + public void init() + { + ServletContext config=getServletContext(); + _contextHandler=((ContextHandler.Context)config).getContextHandler(); + + Handler handler=_contextHandler.getHandler(); + while (handler!=null && !(handler instanceof ServletHandler) && (handler instanceof HandlerWrapper)) + handler=((HandlerWrapper)handler).getHandler(); + _servletHandler = (ServletHandler)handler; + Enumeration e = getInitParameterNames(); + while(e.hasMoreElements()) + { + String param=(String)e.nextElement(); + String value=getInitParameter(param); + String lvalue=value.toLowerCase(Locale.ENGLISH); + if ("nonContextServlets".equals(param)) + { + _nonContextServlets=value.length()>0 && lvalue.startsWith("t"); + } + if ("verbose".equals(param)) + { + _verbose=value.length()>0 && lvalue.startsWith("t"); + } + else + { + if (_parameters==null) + _parameters=new HashMap(); + _parameters.put(param,value); + } + } + } + + /* ------------------------------------------------------------ */ + protected void service(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException + { + // Get the requested path and info + boolean included=false; + String servlet_path=(String)request.getAttribute(Dispatcher.INCLUDE_SERVLET_PATH); + if (servlet_path==null) + servlet_path=request.getServletPath(); + else + included=true; + String path_info = (String)request.getAttribute(Dispatcher.INCLUDE_PATH_INFO); + if (path_info==null) + path_info=request.getPathInfo(); + + // Get the servlet class + String servlet = path_info; + if (servlet==null || servlet.length()<=1 ) + { + response.sendError(404); + return; + } + + + int i0=servlet.charAt(0)=='/'?1:0; + int i1=servlet.indexOf('/',i0); + servlet=i1<0?servlet.substring(i0):servlet.substring(i0,i1); + + // look for a named holder + ServletHolder[] holders = _servletHandler.getServlets(); + ServletHolder holder = getHolder (holders, servlet); + + if (holder!=null) + { + // Found a named servlet (from a user's web.xml file) so + // now we add a mapping for it + if (LOG.isDebugEnabled()) + LOG.debug("Adding servlet mapping for named servlet:"+servlet+":"+URIUtil.addPaths(servlet_path,servlet)+"/*"); + ServletMapping mapping = new ServletMapping(); + mapping.setServletName(servlet); + mapping.setPathSpec(URIUtil.addPaths(servlet_path,servlet)+"/*"); + _servletHandler.setServletMappings((ServletMapping[])ArrayUtil.addToArray(_servletHandler.getServletMappings(), mapping, ServletMapping.class)); + } + else + { + // look for a class mapping + if (servlet.endsWith(".class")) + servlet=servlet.substring(0,servlet.length()-6); + if (servlet==null || servlet.length()==0) + { + response.sendError(404); + return; + } + + synchronized(_servletHandler) + { + // find the entry for the invoker (me) + _invokerEntry=_servletHandler.getHolderEntry(servlet_path); + + // Check for existing mapping (avoid threaded race). + String path=URIUtil.addPaths(servlet_path,servlet); + Map.Entry entry = _servletHandler.getHolderEntry(path); + + if (entry!=null && !entry.equals(_invokerEntry)) + { + // Use the holder + holder=(ServletHolder)entry.getValue(); + } + else + { + // Make a holder + if (LOG.isDebugEnabled()) + LOG.debug("Making new servlet="+servlet+" with path="+path+"/*"); + holder=_servletHandler.addServletWithMapping(servlet, path+"/*"); + + if (_parameters!=null) + holder.setInitParameters(_parameters); + + try {holder.start();} + catch (Exception e) + { + LOG.debug(e); + throw new UnavailableException(e.toString()); + } + + // Check it is from an allowable classloader + if (!_nonContextServlets) + { + Object s=holder.getServlet(); + + if (_contextHandler.getClassLoader()!= + s.getClass().getClassLoader()) + { + try + { + holder.stop(); + } + catch (Exception e) + { + LOG.ignore(e); + } + + LOG.warn("Dynamic servlet "+s+ + " not loaded from context "+ + request.getContextPath()); + throw new UnavailableException("Not in context"); + } + } + + if (_verbose && LOG.isDebugEnabled()) + LOG.debug("Dynamic load '"+servlet+"' at "+path); + } + } + } + + if (holder!=null) + { + final Request baseRequest=(request instanceof Request)?((Request)request):HttpChannel.getCurrentHttpChannel().getRequest(); + holder.handle(baseRequest, + new InvokedRequest(request,included,servlet,servlet_path,path_info), + response); + } + else + { + LOG.info("Can't find holder for servlet: "+servlet); + response.sendError(404); + } + + + } + + /* ------------------------------------------------------------ */ + class InvokedRequest extends HttpServletRequestWrapper + { + String _servletPath; + String _pathInfo; + boolean _included; + + /* ------------------------------------------------------------ */ + InvokedRequest(HttpServletRequest request, + boolean included, + String name, + String servletPath, + String pathInfo) + { + super(request); + _included=included; + _servletPath=URIUtil.addPaths(servletPath,name); + _pathInfo=pathInfo.substring(name.length()+1); + if (_pathInfo.length()==0) + _pathInfo=null; + } + + /* ------------------------------------------------------------ */ + public String getServletPath() + { + if (_included) + return super.getServletPath(); + return _servletPath; + } + + /* ------------------------------------------------------------ */ + public String getPathInfo() + { + if (_included) + return super.getPathInfo(); + return _pathInfo; + } + + /* ------------------------------------------------------------ */ + public Object getAttribute(String name) + { + if (_included) + { + if (name.equals(Dispatcher.INCLUDE_REQUEST_URI)) + return URIUtil.addPaths(URIUtil.addPaths(getContextPath(),_servletPath),_pathInfo); + if (name.equals(Dispatcher.INCLUDE_PATH_INFO)) + return _pathInfo; + if (name.equals(Dispatcher.INCLUDE_SERVLET_PATH)) + return _servletPath; + } + return super.getAttribute(name); + } + } + + + private ServletHolder getHolder(ServletHolder[] holders, String servlet) + { + if (holders == null) + return null; + + ServletHolder holder = null; + for (int i=0; holder==null && i