Save This Page
Home » cactus-1.8.0-src » org.apache.cactus » [javadoc | source]
    1   /* 
    2    * ========================================================================
    3    * 
    4    * Licensed to the Apache Software Foundation (ASF) under one or more
    5    * contributor license agreements.  See the NOTICE file distributed with
    6    * this work for additional information regarding copyright ownership.
    7    * The ASF licenses this file to You under the Apache License, Version 2.0
    8    * (the "License"); you may not use this file except in compliance with
    9    * the License.  You may obtain a copy of the License at
   10    * 
   11    *   http://www.apache.org/licenses/LICENSE-2.0
   12    * 
   13    * Unless required by applicable law or agreed to in writing, software
   14    * distributed under the License is distributed on an "AS IS" BASIS,
   15    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   16    * See the License for the specific language governing permissions and
   17    * limitations under the License.
   18    * 
   19    * ========================================================================
   20    */
   21   package org.apache.cactus;
   22   
   23   import javax.servlet.http.HttpServletRequest;
   24   
   25   import org.apache.cactus.internal.server.ServletUtil;
   26   import org.apache.commons.logging.Log;
   27   import org.apache.commons.logging.LogFactory;
   28   
   29   /**
   30    * Simulate an HTTP URL by breaking it into its different parts.
   31    * <br><code><pre><b>
   32    * URL = "http://" + serverName (including port) + requestURI ? queryString<br>
   33    * requestURI = contextPath + servletPath + pathInfo
   34    * </b></pre></code>
   35    * From the Servlet 2.2 specification :<br>
   36    * <code><pre><ul><li><b>Context Path</b>: The path prefix associated with the
   37    *   ServletContext that this servlet is a part of. If this context is the
   38    *   default context rooted at the base of the web server's URL namespace, this
   39    *   path will be an empty string. Otherwise, this path starts with a "/"
   40    *   character but does not end with a "/" character.</li>
   41    * <li><b>Servlet Path</b>: The path section that directly corresponds to the
   42    *   mapping which activated this request. This path starts with a "/"
   43    *   character.</li>
   44    * <li><b>PathInfo</b>: The part of the request path that is not part of the
   45    *   Context Path or the Servlet Path.</li></ul></pre></code>
   46    * From the Servlet 2.3 specification :<br>
   47    * <code><pre><ul><li><b>Context Path</b>: The path prefix associated with the
   48    *   ServletContext that this servlet is a part of. If this context is the
   49    *   default context rooted at the base of the web server's URL namespace, this
   50    *   path will be an empty string. Otherwise, this path starts with a "/"
   51    *   character but does not end with a "/" character.</li>
   52    * <li><b>Servlet Path</b>: The path section that directly corresponds to the
   53    *   mapping which activated this request. This path starts with a "/"
   54    *   character <b>except in the case where the request is matched with the 
   55    *   "/*" pattern, in which case it is the empty string</b>.</li>
   56    * <li><b>PathInfo</b>: The part of the request path that is not part of the
   57    *   Context Path or the Servlet Path. <b>It is either null if there is no 
   58    *   extra path, or is a string with a leading "/"</b>.</li></ul></pre></code>
   59    *
   60    * @version $Id: ServletURL.java 238991 2004-05-22 11:34:50Z vmassol $
   61    */
   62   public class ServletURL
   63   {
   64       /**
   65        * Name of the parameter in the HTTP request that represents the protocol
   66        * (HTTP, HTTPS, etc) in the URL to simulate. The name is voluntarily long
   67        * so that it will not clash with a user-defined parameter.
   68        */
   69       public static final String URL_PROTOCOL_PARAM = "Cactus_URL_Protocol";
   70   
   71       /**
   72        * Name of the parameter in the HTTP request that represents the Server
   73        * name (+ port) in the URL to simulate. The name is voluntarily long so
   74        * that it will not clash with a user-defined parameter.
   75        */
   76       public static final String URL_SERVER_NAME_PARAM = "Cactus_URL_Server";
   77   
   78       /**
   79        * Name of the parameter in the HTTP request that represents the context
   80        * path in the URL to simulate. The name is voluntarily long so that it
   81        * will not clash with a user-defined parameter.
   82        */
   83       public static final String URL_CONTEXT_PATH_PARAM = 
   84           "Cactus_URL_ContextPath";
   85   
   86       /**
   87        * Name of the parameter in the HTTP request that represents the Servlet
   88        * Path in the URL to simulate. The name is voluntarily long so that it
   89        * will not clash with a user-defined parameter.
   90        */
   91       public static final String URL_SERVLET_PATH_PARAM = 
   92           "Cactus_URL_ServletPath";
   93   
   94       /**
   95        * Name of the parameter in the HTTP request that represents the Path Info
   96        * in the URL to simulate. The name is voluntarily long so that it will not
   97        * clash with a user-defined parameter.
   98        */
   99       public static final String URL_PATH_INFO_PARAM = "Cactus_URL_PathInfo";
  100   
  101       /**
  102        * Name of the parameter in the HTTP request that represents the Query
  103        * String in the URL to simulate. The name is voluntarily long so that it
  104        * will not clash with a user-defined parameter.
  105        */
  106       public static final String URL_QUERY_STRING_PARAM = 
  107           "Cactus_URL_QueryString";
  108   
  109       /**
  110        * Http protocol.
  111        */
  112       public static final String PROTOCOL_HTTP = "http";
  113   
  114       /**
  115        * Https protocol.
  116        */
  117       public static final String PROTOCOL_HTTPS = "https";
  118   
  119       /**
  120        * Default port of the HTTP protocol.
  121        */
  122       private static final int DEFAULT_PORT_HTTP = 80;
  123   
  124       /**
  125        * Default port of HTTP over SSL.
  126        */
  127       private static final int DEFAULT_PORT_HTTPS = 443;
  128   
  129       /**
  130        * The logger.
  131        */
  132       private static final Log LOGGER = LogFactory.getLog(ServletURL.class);
  133   
  134       /**
  135        * The server name to simulate (including port number).
  136        */
  137       private String serverName;
  138   
  139       /**
  140        * The context path to simulate.
  141        */
  142       private String contextPath;
  143   
  144       /**
  145        * The servlet path to simulate.
  146        */
  147       private String servletPath;
  148   
  149       /**
  150        * The Path Info to simulate.
  151        */
  152       private String pathInfo;
  153   
  154       /**
  155        * The Query string.
  156        */
  157       private String queryString;
  158   
  159       /**
  160        * The protocol to use. Default to HTTP.
  161        */
  162       private String protocol = PROTOCOL_HTTP;
  163   
  164       /**
  165        * Default constructor. Need to call the different setters to make this
  166        * a valid object.
  167        */
  168       public ServletURL()
  169       {
  170       }
  171   
  172       /**
  173        * Creates the URL to simulate.
  174        *
  175        * @param theProtocol   the protocol to simulate (either
  176        *                      <code>ServletURL.PROTOCOL_HTTP</code> or
  177        *                      <code>ServletURL.PROTOCOL_HTTPS</code>.
  178        * @param theServerName the server name (and port) in the URL to simulate,
  179        *                      i.e. this is the name that will be returned by the
  180        *                      <code>HttpServletRequest.getServerName()</code> and
  181        *                      <code>HttpServletRequest.getServerPort()</code>. Can
  182        *                      be null. If null, then the server name and port from
  183        *                      the Servlet Redirector will be returned.
  184        * @param theContextPath the webapp context path in the URL to simulate,
  185        *                      i.e. this is the name that will be returned by the
  186        *                      <code>HttpServletRequest.getContextPath()</code>.
  187        *                      Can be null. If null, then the context from the
  188        *                      Servlet Redirector will be used.
  189        *                      Format: "/" + name or an empty string for the 
  190        *                      default context. Must not end with a "/" character.
  191        * @param theServletPath the servlet path in the URL to simulate,
  192        *                      i.e. this is the name that will be returned by the
  193        *                      <code>HttpServletRequest.getServletPath()</code>.
  194        *                      Can be null. If null, then the servlet path from 
  195        *                      the Servlet Redirector will be used.
  196        *                      Format : "/" + name or an empty string.
  197        * @param thePathInfo   the path info in the URL to simulate, i.e. this is
  198        *                      the name that will be returned by the
  199        *                      <code>HttpServletRequest.getPathInfo()</code>. Can
  200        *                      be null. Format : "/" + name.
  201        * @param theQueryString the Query string in the URL to simulate, i.e. this
  202        *                       is the string that will be returned by the
  203        *                       <code>HttpServletResquest.getQueryString()</code>.
  204        *                       Can be null.
  205        */
  206       public ServletURL(String theProtocol, String theServerName, 
  207           String theContextPath, String theServletPath, String thePathInfo, 
  208           String theQueryString)
  209       {
  210           setProtocol(theProtocol);
  211           setServerName(theServerName);
  212           setContextPath(theContextPath);
  213           setServletPath(theServletPath);
  214           setPathInfo(thePathInfo);
  215           setQueryString(theQueryString);
  216       }
  217   
  218       /**
  219        * Creates the URL to simulate, using the default HTTP protocol.
  220        *
  221        * @param theServerName the server name (and port) in the URL to simulate,
  222        *                      i.e. this is the name that will be returned by the
  223        *                      <code>HttpServletRequest.getServerName()</code> and
  224        *                      <code>HttpServletRequest.getServerPort()</code>. Can
  225        *                      be null. If null, then the server name and port from
  226        *                      the Servlet Redirector will be returned.
  227        * @param theContextPath the webapp context path in the URL to simulate,
  228        *                      i.e. this is the name that will be returned by the
  229        *                      <code>HttpServletRequest.getContextPath()</code>.
  230        *                      Can be null. If null, then the context from the
  231        *                      Servlet Redirector will be used.
  232        *                      Format: "/" + name or an empty string for the 
  233        *                      default context. Must not end with a "/" character.
  234        * @param theServletPath the servlet path in the URL to simulate,
  235        *                      i.e. this is the name that will be returned by the
  236        *                      <code>HttpServletRequest.getServletPath()</code>.
  237        *                      Can be null. If null, then the servlet path from 
  238        *                      the Servlet Redirector will be used.
  239        *                      Format : "/" + name or an empty string.
  240        * @param thePathInfo   the path info in the URL to simulate, i.e. this is
  241        *                      the name that will be returned by the
  242        *                      <code>HttpServletRequest.getPathInfo()</code>. Can
  243        *                      be null. Format : "/" + name.
  244        * @param theQueryString the Query string in the URL to simulate, i.e. this
  245        *                       is the string that will be returned by the
  246        *                       <code>HttpServletResquest.getQueryString()</code>.
  247        *                       Can be null.
  248        */
  249       public ServletURL(String theServerName, String theContextPath, 
  250           String theServletPath, String thePathInfo, String theQueryString)
  251       {
  252           this(PROTOCOL_HTTP, theServerName, theContextPath, theServletPath, 
  253               thePathInfo, theQueryString);
  254       }
  255   
  256       /**
  257        * @return the protocol used to connect to the URL (HTTP, HTTPS, etc).
  258        */
  259       public String getProtocol()
  260       {
  261           return this.protocol;
  262       }
  263   
  264       /**
  265        * Sets the protocol to simulate (either
  266        * <code>ServletURL.PROTOCOL_HTTP</code> or
  267        * <code>ServletURL.PROTOCOL_HTTPS</code>. If parameter is null then
  268        * PROTOCOL_HTTP is assumed.
  269        *
  270        * @param theProtocol the protocol to simulate
  271        */
  272       public void setProtocol(String theProtocol)
  273       {
  274           // Only HTTP and HTTPS are currently supported.
  275           if ((!theProtocol.equals(PROTOCOL_HTTP))
  276               && (!theProtocol.equals(PROTOCOL_HTTPS)))
  277           {
  278               throw new RuntimeException("Invalid protocol [" + theProtocol
  279                   + "]. Currently supported protocols are ["
  280                   + PROTOCOL_HTTP + "] and ["
  281                   + PROTOCOL_HTTPS + "].");
  282           }
  283   
  284           this.protocol = theProtocol;
  285       }
  286   
  287       /**
  288        * @return the simulated URL server name (including the port number)
  289        */
  290       public String getServerName()
  291       {
  292           return this.serverName;
  293       }
  294   
  295       /**
  296        * Sets the server name (and port) in the URL to simulate, ie this is the
  297        * name that will be returned by the
  298        * <code>HttpServletRequest.getServerName()</code> and
  299        * <code>HttpServletRequest.getServerPort()</code>. Does not need to be
  300        * set. If not set or null, then the server name and port from the Servlet
  301        * Redirector will be returned.
  302        *
  303        * @param theServerName the server name and port (ex:
  304        *        "jakarta.apache.org:80")
  305        */
  306       public void setServerName(String theServerName)
  307       {
  308           this.serverName = theServerName;
  309       }
  310   
  311       /**
  312        * Returns the host name.
  313        * 
  314        * <p>
  315        *   The host name is extracted from the specified server name (as in 
  316        *   <code><strong>jakarta.apache.org</strong>:80</code>). If the server
  317        *   name has not been set, this method will return <code>null</code>.
  318        * </p>
  319        * 
  320        * @return the simulated URL server name (excluding the port number)
  321        */
  322       public String getHost()
  323       {
  324           String host = getServerName();
  325   
  326           if (host != null)
  327           {
  328               int pos = host.indexOf(":");
  329   
  330               if (pos > 0)
  331               {
  332                   host = host.substring(0, pos);
  333               }
  334           }
  335   
  336           return host;
  337       }
  338   
  339       /**
  340        * Returns the port.
  341        * 
  342        * <p>
  343        *   The port is extracted from the specified server name (as in 
  344        *   <code>jakarta.apache.org:<strong>80</strong></code>). If the server
  345        *   name doesn't contain a port number, the default port number is returned
  346        *   (80 for HTTP, 443 for HTTP over SSL). If a port number is specified but
  347        *   illegal, or the server name has not been set, this method will return
  348        *   -1.
  349        * </p>
  350        * 
  351        * @return the simulated port number or -1 if an illegal port has been
  352        *          specified
  353        */
  354       public int getPort()
  355       {
  356           int port = -1;
  357   
  358           if (getServerName() != null)
  359           {
  360               int pos = getServerName().indexOf(":");
  361   
  362               if (pos < 0)
  363               {
  364                   // the server name doesn't contain a port specification, so use
  365                   // the default port for the protocol
  366                   port = getDefaultPort();
  367               }
  368               else
  369               {
  370                   // parse the port encoded in the server name
  371                   try
  372                   {
  373                       port = Integer.parseInt(getServerName().substring(pos + 1));
  374                       if (port < 0)
  375                       {
  376                           port = -1;
  377                       }
  378                   }
  379                   catch (NumberFormatException e)
  380                   {
  381                       port = -1;
  382                   }
  383               }
  384           }
  385   
  386           return port;
  387       }
  388   
  389       /**
  390        * @return the simulated URL context path
  391        */
  392       public String getContextPath()
  393       {
  394           return this.contextPath;
  395       }
  396   
  397       /**
  398        * Sets the webapp context path in the URL to simulate, ie this is the
  399        * name that will be returned by the
  400        * <code>HttpServletRequest.getContextPath()</code>. If not set, the
  401        * context from the Servlet Redirector will be returned. Format: "/" +
  402        * name or an empty string for the default context. If not an empty
  403        * string the last character must not be "/".
  404        *
  405        * @param theContextPath the context path to simulate
  406        */
  407       public void setContextPath(String theContextPath)
  408       {
  409           if ((theContextPath != null) && (theContextPath.length() > 0))
  410           {
  411               if (!theContextPath.startsWith("/"))
  412               {
  413                   throw new IllegalArgumentException("The Context Path must"
  414                       + " start with a \"/\" character.");
  415               }
  416               if (theContextPath.endsWith("/"))
  417               {
  418                   throw new IllegalArgumentException("The Context Path must not"
  419                       + " end with a \"/\" character.");                
  420               }
  421           }
  422   
  423           this.contextPath = theContextPath;
  424       }
  425   
  426       /**
  427        * @return the simulated URL servlet path
  428        */
  429       public String getServletPath()
  430       {
  431           return this.servletPath;
  432       }
  433   
  434       /**
  435        * Sets the servlet path in the URL to simulate, ie this is the name that
  436        * will be returned by the <code>HttpServletRequest.getServletPath()</code>.
  437        * If null then the servlet path from the Servlet Redirector will be
  438        * returned. Format : "/" + name or an empty string.
  439        *
  440        * @param theServletPath the servlet path to simulate
  441        */
  442       public void setServletPath(String theServletPath)
  443       {
  444           if ((theServletPath != null) && (theServletPath.length() > 0))
  445           {
  446               if (!theServletPath.startsWith("/"))
  447               {
  448                   throw new IllegalArgumentException("The Servlet Path must"
  449                       + " start with a \"/\" character.");
  450               }            
  451           }
  452   
  453           this.servletPath = theServletPath;
  454       }
  455   
  456       /**
  457        * @return the simulated URL path info
  458        */
  459       public String getPathInfo()
  460       {
  461           return this.pathInfo;
  462       }
  463   
  464       /**
  465        * Sets the path info in the URL to simulate, ie this is the name that will
  466        * be returned by the <code>HttpServletRequest.getPathInfo()</code>. 
  467        * If null then no path info will be set (and the Path Info from the 
  468        * Servlet Redirector will <b>not</b> be used). 
  469        * Format : "/" + name.
  470        *
  471        * @param thePathInfo the path info to simulate
  472        */
  473       public void setPathInfo(String thePathInfo)
  474       {
  475           if ((thePathInfo != null) && (thePathInfo.length() == 0))
  476           { 
  477               throw new IllegalArgumentException("The Path Info must"
  478                   + " not be an empty string. Use null if you don't"
  479                   + " want to have a path info.");
  480           }
  481           else if (thePathInfo != null)
  482           {
  483               if (!thePathInfo.startsWith("/"))
  484               {
  485                   throw new IllegalArgumentException("The Path Info must"
  486                       + " start with a \"/\" character.");
  487               }            
  488           }
  489   
  490           this.pathInfo = thePathInfo;
  491       }
  492   
  493       /**
  494        * @return the simulated Query String
  495        */
  496       public String getQueryString()
  497       {
  498           return this.queryString;
  499       }
  500   
  501       /**
  502        * Sets the Query string in the URL to simulate, ie this is the string that
  503        * will be returned by the
  504        * <code>HttpServletResquest.getQueryString()</code>. If not set, the
  505        * query string from the Servlet Redirector will be returned.
  506        *
  507        * @param theQueryString the query string to simulate
  508        */
  509       public void setQueryString(String theQueryString)
  510       {
  511           this.queryString = theQueryString;
  512       }
  513   
  514       /**
  515        * @return the path (contextPath + servletPath + pathInfo) or null if
  516        *         not set
  517        */
  518       public String getPath()
  519       {
  520           String path;
  521   
  522           path = (getContextPath() == null) ? "" : getContextPath();
  523           path += ((getServletPath() == null) ? "" : getServletPath());
  524           path += ((getPathInfo() == null) ? "" : getPathInfo());
  525   
  526           if (path.length() == 0)
  527           {
  528               path = null;
  529           }
  530   
  531           return path;
  532       }
  533   
  534       /**
  535        * Saves the current URL to a <code>WebRequest</code> object.
  536        *
  537        * @param theRequest the object to which the current URL should be saved to
  538        */
  539       public void saveToRequest(WebRequest theRequest)
  540       {
  541           // Note: All these pareameters are passed in the URL. This is to allow
  542           // the user to send whatever he wants in the request body. For example
  543           // a file, ...
  544           theRequest.addParameter(URL_PROTOCOL_PARAM, getProtocol(), 
  545               WebRequest.GET_METHOD);
  546   
  547           if (getServerName() != null)
  548           {
  549               theRequest.addParameter(URL_SERVER_NAME_PARAM, getServerName(), 
  550                   WebRequest.GET_METHOD);
  551           }
  552   
  553           if (getContextPath() != null)
  554           {
  555               theRequest.addParameter(URL_CONTEXT_PATH_PARAM, getContextPath(), 
  556                   WebRequest.GET_METHOD);
  557           }
  558   
  559           if (getServletPath() != null)
  560           {
  561               theRequest.addParameter(URL_SERVLET_PATH_PARAM, getServletPath(), 
  562                   WebRequest.GET_METHOD);
  563           }
  564   
  565           if (getPathInfo() != null)
  566           {
  567               theRequest.addParameter(URL_PATH_INFO_PARAM, getPathInfo(), 
  568                   WebRequest.GET_METHOD);
  569           }
  570   
  571           if (getQueryString() != null)
  572           {
  573               theRequest.addParameter(URL_QUERY_STRING_PARAM, getQueryString(), 
  574                   WebRequest.GET_METHOD);
  575           }
  576       }
  577   
  578       /**
  579        * Creates a <code>ServletURL</code> object by loading it's values from the
  580        * HTTP request.
  581        *
  582        * @param theRequest the incoming HTTP request.
  583        * @return the <code>ServletURL</code> object unserialized from the HTTP
  584        *         request
  585        */
  586       public static ServletURL loadFromRequest(HttpServletRequest theRequest)
  587       {
  588           String qString = theRequest.getQueryString();
  589           boolean isDefined = false;
  590   
  591           ServletURL url = new ServletURL();
  592   
  593           String protocol = ServletUtil.getQueryStringParameter(qString, 
  594               URL_PROTOCOL_PARAM);
  595   
  596           if (protocol != null)
  597           {
  598               isDefined = true;
  599               url.setProtocol(protocol);
  600           }
  601   
  602           String serverName = ServletUtil.getQueryStringParameter(qString, 
  603               URL_SERVER_NAME_PARAM);
  604   
  605           if (serverName != null)
  606           {
  607               isDefined = true;
  608               url.setServerName(serverName);
  609           }
  610   
  611           String contextPath = ServletUtil.getQueryStringParameter(qString, 
  612               URL_CONTEXT_PATH_PARAM);
  613   
  614           if (contextPath != null)
  615           {
  616               isDefined = true;
  617               url.setContextPath(contextPath);
  618           }
  619   
  620           String servletPath = ServletUtil.getQueryStringParameter(qString, 
  621               URL_SERVLET_PATH_PARAM);
  622   
  623           if (servletPath != null)
  624           {
  625               isDefined = true;
  626               url.setServletPath(servletPath);
  627           }
  628   
  629           String pathInfo = ServletUtil.getQueryStringParameter(qString, 
  630               URL_PATH_INFO_PARAM);
  631   
  632           if (pathInfo != null)
  633           {
  634               isDefined = true;
  635               url.setPathInfo(pathInfo);
  636           }
  637   
  638           String queryString = ServletUtil.getQueryStringParameter(qString, 
  639               URL_QUERY_STRING_PARAM);
  640   
  641           if (queryString != null)
  642           {
  643               isDefined = true;
  644               url.setQueryString(queryString);
  645           }
  646   
  647           if (!isDefined)
  648           {
  649               LOGGER.debug("Undefined simulation URL");
  650               url = null;
  651           }
  652           else
  653           {
  654               LOGGER.debug("Simulation URL = [" + url + "]");
  655           }
  656   
  657           return url;
  658       }
  659   
  660       /**
  661        * @return a string representation
  662        */
  663       public String toString()
  664       {
  665           StringBuffer buffer = new StringBuffer();
  666   
  667           buffer.append("protocol = [" + getProtocol() + "], ");
  668           buffer.append("host name = [" + getHost() + "], ");
  669           buffer.append("port = [" + getPort() + "], ");
  670           buffer.append("context path = [" + getContextPath() + "], ");
  671           buffer.append("servlet path = [" + getServletPath() + "], ");
  672           buffer.append("path info = [" + getPathInfo() + "], ");
  673           buffer.append("query string = [" + getQueryString() + "]");
  674   
  675           return buffer.toString();
  676       }
  677   
  678       /**
  679        * Returns the default port for the protocol.
  680        * 
  681        * @return the default port (80 for HTTP, 443 for HTTP over SSL)
  682        */
  683       private int getDefaultPort()
  684       {
  685           if (PROTOCOL_HTTPS.equals(getProtocol()))
  686           {
  687               return DEFAULT_PORT_HTTPS;
  688           }
  689           else
  690           {
  691               return DEFAULT_PORT_HTTP;
  692           }
  693       }
  694   
  695   }

Save This Page
Home » cactus-1.8.0-src » org.apache.cactus » [javadoc | source]