Mercurial Hosting > luan
diff src/org/eclipse/jetty/server/Dispatcher.java @ 802:3428c60d7cfc
replace jetty jars with source
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Wed, 07 Sep 2016 21:15:48 -0600 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/org/eclipse/jetty/server/Dispatcher.java Wed Sep 07 21:15:48 2016 -0600 @@ -0,0 +1,550 @@ +// +// ======================================================================== +// 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.server; + +import java.io.IOException; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; + +import javax.servlet.DispatcherType; +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.eclipse.jetty.server.handler.ContextHandler; +import org.eclipse.jetty.util.Attributes; +import org.eclipse.jetty.util.LazyList; +import org.eclipse.jetty.util.MultiMap; +import org.eclipse.jetty.util.UrlEncoded; + +/* ------------------------------------------------------------ */ +/** Servlet RequestDispatcher. + * + * + */ +public class Dispatcher implements RequestDispatcher +{ + /** Dispatch include attribute names */ + public final static String __INCLUDE_PREFIX="javax.servlet.include."; + + /** Dispatch include attribute names */ + public final static String __FORWARD_PREFIX="javax.servlet.forward."; + + /** JSP attributes */ + public final static String __JSP_FILE="org.apache.catalina.jsp_file"; + + /* ------------------------------------------------------------ */ + private final ContextHandler _contextHandler; + private final String _uri; + private final String _path; + private final String _dQuery; + private final String _named; + + /* ------------------------------------------------------------ */ + /** + * @param contextHandler + * @param uri + * @param pathInContext + * @param query + */ + public Dispatcher(ContextHandler contextHandler, String uri, String pathInContext, String query) + { + _contextHandler=contextHandler; + _uri=uri; + _path=pathInContext; + _dQuery=query; + _named=null; + } + + + /* ------------------------------------------------------------ */ + /** Constructor. + * @param contextHandler + * @param name + */ + public Dispatcher(ContextHandler contextHandler,String name) + throws IllegalStateException + { + _contextHandler=contextHandler; + _named=name; + _uri=null; + _path=null; + _dQuery=null; + } + + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.RequestDispatcher#forward(javax.servlet.ServletRequest, javax.servlet.ServletResponse) + */ + public void forward(ServletRequest request, ServletResponse response) throws ServletException, IOException + { + forward(request, response, DispatcherType.FORWARD); + } + + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.RequestDispatcher#forward(javax.servlet.ServletRequest, javax.servlet.ServletResponse) + */ + public void error(ServletRequest request, ServletResponse response) throws ServletException, IOException + { + forward(request, response, DispatcherType.ERROR); + } + + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.RequestDispatcher#include(javax.servlet.ServletRequest, javax.servlet.ServletResponse) + */ + public void include(ServletRequest request, ServletResponse response) throws ServletException, IOException + { + Request baseRequest=(request instanceof Request)?((Request)request):AbstractHttpConnection.getCurrentConnection().getRequest(); + + + if (!(request instanceof HttpServletRequest)) + request = new ServletRequestHttpWrapper(request); + if (!(response instanceof HttpServletResponse)) + response = new ServletResponseHttpWrapper(response); + + + // TODO - allow stream or writer???? + + final DispatcherType old_type = baseRequest.getDispatcherType(); + final Attributes old_attr=baseRequest.getAttributes(); + MultiMap old_params=baseRequest.getParameters(); + try + { + baseRequest.setDispatcherType(DispatcherType.INCLUDE); + baseRequest.getConnection().include(); + if (_named!=null) + _contextHandler.handle(_named,baseRequest, (HttpServletRequest)request, (HttpServletResponse)response); + else + { + String query=_dQuery; + + if (query!=null) + { + // force parameter extraction + if (old_params==null) + { + baseRequest.extractParameters(); + old_params=baseRequest.getParameters(); + } + + MultiMap parameters=new MultiMap(); + UrlEncoded.decodeTo(query,parameters,baseRequest.getCharacterEncoding()); + + if (old_params!=null && old_params.size()>0) + { + // Merge parameters. + Iterator iter = old_params.entrySet().iterator(); + while (iter.hasNext()) + { + Map.Entry entry = (Map.Entry)iter.next(); + String name=(String)entry.getKey(); + Object values=entry.getValue(); + for (int i=0;i<LazyList.size(values);i++) + parameters.add(name, LazyList.get(values, i)); + } + } + baseRequest.setParameters(parameters); + } + + IncludeAttributes attr = new IncludeAttributes(old_attr); + + attr._requestURI=_uri; + attr._contextPath=_contextHandler.getContextPath(); + attr._servletPath=null; // set by ServletHandler + attr._pathInfo=_path; + attr._query=query; + + baseRequest.setAttributes(attr); + + _contextHandler.handle(_path,baseRequest, (HttpServletRequest)request, (HttpServletResponse)response); + } + } + finally + { + baseRequest.setAttributes(old_attr); + baseRequest.getConnection().included(); + baseRequest.setParameters(old_params); + baseRequest.setDispatcherType(old_type); + } + } + + + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.RequestDispatcher#forward(javax.servlet.ServletRequest, javax.servlet.ServletResponse) + */ + protected void forward(ServletRequest request, ServletResponse response, DispatcherType dispatch) throws ServletException, IOException + { + Request baseRequest=(request instanceof Request)?((Request)request):AbstractHttpConnection.getCurrentConnection().getRequest(); + Response base_response=baseRequest.getResponse(); + response.resetBuffer(); + base_response.fwdReset(); + + + if (!(request instanceof HttpServletRequest)) + request = new ServletRequestHttpWrapper(request); + if (!(response instanceof HttpServletResponse)) + response = new ServletResponseHttpWrapper(response); + + final boolean old_handled=baseRequest.isHandled(); + final String old_uri=baseRequest.getRequestURI(); + final String old_context_path=baseRequest.getContextPath(); + final String old_servlet_path=baseRequest.getServletPath(); + final String old_path_info=baseRequest.getPathInfo(); + final String old_query=baseRequest.getQueryString(); + final Attributes old_attr=baseRequest.getAttributes(); + final DispatcherType old_type=baseRequest.getDispatcherType(); + MultiMap<String> old_params=baseRequest.getParameters(); + + try + { + baseRequest.setHandled(false); + baseRequest.setDispatcherType(dispatch); + + if (_named!=null) + _contextHandler.handle(_named,baseRequest, (HttpServletRequest)request, (HttpServletResponse)response); + else + { + + // process any query string from the dispatch URL + String query=_dQuery; + if (query!=null) + { + // force parameter extraction + if (old_params==null) + { + baseRequest.extractParameters(); + old_params=baseRequest.getParameters(); + } + + baseRequest.mergeQueryString(query); + } + + ForwardAttributes attr = new ForwardAttributes(old_attr); + + //If we have already been forwarded previously, then keep using the established + //original value. Otherwise, this is the first forward and we need to establish the values. + //Note: the established value on the original request for pathInfo and + //for queryString is allowed to be null, but cannot be null for the other values. + if (old_attr.getAttribute(FORWARD_REQUEST_URI) != null) + { + attr._pathInfo=(String)old_attr.getAttribute(FORWARD_PATH_INFO); + attr._query=(String)old_attr.getAttribute(FORWARD_QUERY_STRING); + attr._requestURI=(String)old_attr.getAttribute(FORWARD_REQUEST_URI); + attr._contextPath=(String)old_attr.getAttribute(FORWARD_CONTEXT_PATH); + attr._servletPath=(String)old_attr.getAttribute(FORWARD_SERVLET_PATH); + } + else + { + attr._pathInfo=old_path_info; + attr._query=old_query; + attr._requestURI=old_uri; + attr._contextPath=old_context_path; + attr._servletPath=old_servlet_path; + } + + baseRequest.setRequestURI(_uri); + baseRequest.setContextPath(_contextHandler.getContextPath()); + baseRequest.setServletPath(null); + baseRequest.setPathInfo(_uri); + baseRequest.setAttributes(attr); + + _contextHandler.handle(_path,baseRequest, (HttpServletRequest)request, (HttpServletResponse)response); + + if (!baseRequest.getAsyncContinuation().isAsyncStarted()) + commitResponse(response,baseRequest); + } + } + finally + { + baseRequest.setHandled(old_handled); + baseRequest.setRequestURI(old_uri); + baseRequest.setContextPath(old_context_path); + baseRequest.setServletPath(old_servlet_path); + baseRequest.setPathInfo(old_path_info); + baseRequest.setAttributes(old_attr); + baseRequest.setParameters(old_params); + baseRequest.setQueryString(old_query); + baseRequest.setDispatcherType(old_type); + } + } + + + /* ------------------------------------------------------------ */ + private void commitResponse(ServletResponse response, Request baseRequest) throws IOException + { + if (baseRequest.getResponse().isWriting()) + { + try + { + response.getWriter().close(); + } + catch (IllegalStateException e) + { + response.getOutputStream().close(); + } + } + else + { + try + { + response.getOutputStream().close(); + } + catch (IllegalStateException e) + { + response.getWriter().close(); + } + } + } + + + /* ------------------------------------------------------------ */ + /* ------------------------------------------------------------ */ + /* ------------------------------------------------------------ */ + private class ForwardAttributes implements Attributes + { + final Attributes _attr; + + String _requestURI; + String _contextPath; + String _servletPath; + String _pathInfo; + String _query; + + ForwardAttributes(Attributes attributes) + { + _attr=attributes; + } + + /* ------------------------------------------------------------ */ + public Object getAttribute(String key) + { + if (Dispatcher.this._named==null) + { + if (key.equals(FORWARD_PATH_INFO)) + return _pathInfo; + if (key.equals(FORWARD_REQUEST_URI)) + return _requestURI; + if (key.equals(FORWARD_SERVLET_PATH)) + return _servletPath; + if (key.equals(FORWARD_CONTEXT_PATH)) + return _contextPath; + if (key.equals(FORWARD_QUERY_STRING)) + return _query; + } + + if (key.startsWith(__INCLUDE_PREFIX)) + return null; + + return _attr.getAttribute(key); + } + + /* ------------------------------------------------------------ */ + public Enumeration getAttributeNames() + { + HashSet set=new HashSet(); + Enumeration e=_attr.getAttributeNames(); + while(e.hasMoreElements()) + { + String name=(String)e.nextElement(); + if (!name.startsWith(__INCLUDE_PREFIX) && + !name.startsWith(__FORWARD_PREFIX)) + set.add(name); + } + + if (_named==null) + { + if (_pathInfo!=null) + set.add(FORWARD_PATH_INFO); + else + set.remove(FORWARD_PATH_INFO); + set.add(FORWARD_REQUEST_URI); + set.add(FORWARD_SERVLET_PATH); + set.add(FORWARD_CONTEXT_PATH); + if (_query!=null) + set.add(FORWARD_QUERY_STRING); + else + set.remove(FORWARD_QUERY_STRING); + } + + return Collections.enumeration(set); + } + + /* ------------------------------------------------------------ */ + public void setAttribute(String key, Object value) + { + if (_named==null && key.startsWith("javax.servlet.")) + { + if (key.equals(FORWARD_PATH_INFO)) + _pathInfo=(String)value; + else if (key.equals(FORWARD_REQUEST_URI)) + _requestURI=(String)value; + else if (key.equals(FORWARD_SERVLET_PATH)) + _servletPath=(String)value; + else if (key.equals(FORWARD_CONTEXT_PATH)) + _contextPath=(String)value; + else if (key.equals(FORWARD_QUERY_STRING)) + _query=(String)value; + + else if (value==null) + _attr.removeAttribute(key); + else + _attr.setAttribute(key,value); + } + else if (value==null) + _attr.removeAttribute(key); + else + _attr.setAttribute(key,value); + } + + /* ------------------------------------------------------------ */ + @Override + public String toString() + { + return "FORWARD+"+_attr.toString(); + } + + /* ------------------------------------------------------------ */ + public void clearAttributes() + { + throw new IllegalStateException(); + } + + /* ------------------------------------------------------------ */ + public void removeAttribute(String name) + { + setAttribute(name,null); + } + } + + /* ------------------------------------------------------------ */ + private class IncludeAttributes implements Attributes + { + final Attributes _attr; + + String _requestURI; + String _contextPath; + String _servletPath; + String _pathInfo; + String _query; + + IncludeAttributes(Attributes attributes) + { + _attr=attributes; + } + + /* ------------------------------------------------------------ */ + /* ------------------------------------------------------------ */ + /* ------------------------------------------------------------ */ + public Object getAttribute(String key) + { + if (Dispatcher.this._named==null) + { + if (key.equals(INCLUDE_PATH_INFO)) return _pathInfo; + if (key.equals(INCLUDE_SERVLET_PATH)) return _servletPath; + if (key.equals(INCLUDE_CONTEXT_PATH)) return _contextPath; + if (key.equals(INCLUDE_QUERY_STRING)) return _query; + if (key.equals(INCLUDE_REQUEST_URI)) return _requestURI; + } + else if (key.startsWith(__INCLUDE_PREFIX)) + return null; + + + return _attr.getAttribute(key); + } + + /* ------------------------------------------------------------ */ + public Enumeration getAttributeNames() + { + HashSet set=new HashSet(); + Enumeration e=_attr.getAttributeNames(); + while(e.hasMoreElements()) + { + String name=(String)e.nextElement(); + if (!name.startsWith(__INCLUDE_PREFIX)) + set.add(name); + } + + if (_named==null) + { + if (_pathInfo!=null) + set.add(INCLUDE_PATH_INFO); + else + set.remove(INCLUDE_PATH_INFO); + set.add(INCLUDE_REQUEST_URI); + set.add(INCLUDE_SERVLET_PATH); + set.add(INCLUDE_CONTEXT_PATH); + if (_query!=null) + set.add(INCLUDE_QUERY_STRING); + else + set.remove(INCLUDE_QUERY_STRING); + } + + return Collections.enumeration(set); + } + + /* ------------------------------------------------------------ */ + public void setAttribute(String key, Object value) + { + if (_named==null && key.startsWith("javax.servlet.")) + { + if (key.equals(INCLUDE_PATH_INFO)) _pathInfo=(String)value; + else if (key.equals(INCLUDE_REQUEST_URI)) _requestURI=(String)value; + else if (key.equals(INCLUDE_SERVLET_PATH)) _servletPath=(String)value; + else if (key.equals(INCLUDE_CONTEXT_PATH)) _contextPath=(String)value; + else if (key.equals(INCLUDE_QUERY_STRING)) _query=(String)value; + else if (value==null) + _attr.removeAttribute(key); + else + _attr.setAttribute(key,value); + } + else if (value==null) + _attr.removeAttribute(key); + else + _attr.setAttribute(key,value); + } + + /* ------------------------------------------------------------ */ + @Override + public String toString() + { + return "INCLUDE+"+_attr.toString(); + } + + /* ------------------------------------------------------------ */ + public void clearAttributes() + { + throw new IllegalStateException(); + } + + /* ------------------------------------------------------------ */ + public void removeAttribute(String name) + { + setAttribute(name,null); + } + } +}