Save This Page
Home » apache-tomcat-6.0.16-src » org.apache » catalina » connector » [javadoc | source]
    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *      http://www.apache.org/licenses/LICENSE-2.0
   10    *
   11    * Unless required by applicable law or agreed to in writing, software
   12    * distributed under the License is distributed on an "AS IS" BASIS,
   13    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    * See the License for the specific language governing permissions and
   15    * limitations under the License.
   16    */
   17   
   18   
   19   package org.apache.catalina.connector;
   20   
   21   import java.lang.reflect.Method;
   22   import java.net.URLEncoder;
   23   import java.util.HashMap;
   24   
   25   import javax.management.MBeanRegistration;
   26   import javax.management.MBeanServer;
   27   import javax.management.MalformedObjectNameException;
   28   import javax.management.ObjectName;
   29   
   30   import org.apache.catalina.Container;
   31   import org.apache.catalina.Lifecycle;
   32   import org.apache.catalina.LifecycleException;
   33   import org.apache.catalina.LifecycleListener;
   34   import org.apache.catalina.Service;
   35   import org.apache.catalina.core.StandardEngine;
   36   import org.apache.catalina.util.LifecycleSupport;
   37   import org.apache.catalina.util.StringManager;
   38   import org.apache.coyote.Adapter;
   39   import org.apache.coyote.ProtocolHandler;
   40   import org.apache.juli.logging.Log;
   41   import org.apache.juli.logging.LogFactory;
   42   import org.apache.tomcat.util.IntrospectionUtils;
   43   import org.apache.tomcat.util.http.mapper.Mapper;
   44   import org.apache.tomcat.util.modeler.Registry;
   45   
   46   
   47   /**
   48    * Implementation of a Coyote connector for Tomcat 5.x.
   49    *
   50    * @author Craig R. McClanahan
   51    * @author Remy Maucherat
   52    * @version $Revision: 586738 $ $Date: 2007-10-20 16:57:18 +0200 (sam., 20 oct. 2007) $
   53    */
   54   
   55   
   56   public class Connector
   57       implements Lifecycle, MBeanRegistration
   58   {
   59       private static Log log = LogFactory.getLog(Connector.class);
   60   
   61   
   62       /**
   63        * Alternate flag to enable recycling of facades.
   64        */
   65       public static final boolean RECYCLE_FACADES =
   66           Boolean.valueOf(System.getProperty("org.apache.catalina.connector.RECYCLE_FACADES", "false")).booleanValue();
   67   
   68   
   69       // ------------------------------------------------------------ Constructor
   70   
   71   
   72       public Connector()
   73           throws Exception {
   74           this(null);
   75       }
   76   
   77       public Connector(String protocol)
   78           throws Exception {
   79           setProtocol(protocol);
   80           // Instantiate protocol handler
   81           try {
   82               Class clazz = Class.forName(protocolHandlerClassName);
   83               this.protocolHandler = (ProtocolHandler) clazz.newInstance();
   84           } catch (Exception e) {
   85               log.error
   86                   (sm.getString
   87                    ("coyoteConnector.protocolHandlerInstantiationFailed", e));
   88           }
   89       }
   90   
   91   
   92       // ----------------------------------------------------- Instance Variables
   93   
   94   
   95       /**
   96        * The <code>Service</code> we are associated with (if any).
   97        */
   98       protected Service service = null;
   99   
  100   
  101       /**
  102        * Do we allow TRACE ?
  103        */
  104       protected boolean allowTrace = false;
  105   
  106   
  107       /**
  108        * The Container used for processing requests received by this Connector.
  109        */
  110       protected Container container = null;
  111   
  112   
  113       /**
  114        * Use "/" as path for session cookies ?
  115        */
  116       protected boolean emptySessionPath = false;
  117   
  118   
  119       /**
  120        * The "enable DNS lookups" flag for this Connector.
  121        */
  122       protected boolean enableLookups = false;
  123   
  124   
  125       /*
  126        * Is generation of X-Powered-By response header enabled/disabled?
  127        */
  128       protected boolean xpoweredBy = false;
  129   
  130   
  131       /**
  132        * Descriptive information about this Connector implementation.
  133        */
  134       protected static final String info =
  135           "org.apache.catalina.connector.Connector/2.1";
  136   
  137   
  138       /**
  139        * The lifecycle event support for this component.
  140        */
  141       protected LifecycleSupport lifecycle = new LifecycleSupport(this);
  142   
  143   
  144       /**
  145        * The port number on which we listen for requests.
  146        */
  147       protected int port = 0;
  148   
  149   
  150       /**
  151        * The server name to which we should pretend requests to this Connector
  152        * were directed.  This is useful when operating Tomcat behind a proxy
  153        * server, so that redirects get constructed accurately.  If not specified,
  154        * the server name included in the <code>Host</code> header is used.
  155        */
  156       protected String proxyName = null;
  157   
  158   
  159       /**
  160        * The server port to which we should pretent requests to this Connector
  161        * were directed.  This is useful when operating Tomcat behind a proxy
  162        * server, so that redirects get constructed accurately.  If not specified,
  163        * the port number specified by the <code>port</code> property is used.
  164        */
  165       protected int proxyPort = 0;
  166   
  167   
  168       /**
  169        * The redirect port for non-SSL to SSL redirects.
  170        */
  171       protected int redirectPort = 443;
  172   
  173   
  174       /**
  175        * The request scheme that will be set on all requests received
  176        * through this connector.
  177        */
  178       protected String scheme = "http";
  179   
  180   
  181       /**
  182        * The secure connection flag that will be set on all requests received
  183        * through this connector.
  184        */
  185       protected boolean secure = false;
  186   
  187   
  188       /**
  189        * The string manager for this package.
  190        */
  191       protected StringManager sm =
  192           StringManager.getManager(Constants.Package);
  193   
  194   
  195       /**
  196        * Maximum size of a POST which will be automatically parsed by the
  197        * container. 2MB by default.
  198        */
  199       protected int maxPostSize = 2 * 1024 * 1024;
  200   
  201   
  202       /**
  203        * Maximum size of a POST which will be saved by the container
  204        * during authentication. 4kB by default
  205        */
  206       protected int maxSavePostSize = 4 * 1024;
  207   
  208   
  209       /**
  210        * Has this component been initialized yet?
  211        */
  212       protected boolean initialized = false;
  213   
  214   
  215       /**
  216        * Has this component been started yet?
  217        */
  218       protected boolean started = false;
  219   
  220   
  221       /**
  222        * The shutdown signal to our background thread
  223        */
  224       protected boolean stopped = false;
  225   
  226       /**
  227        * Flag to use IP-based virtual hosting.
  228        */
  229       protected boolean useIPVHosts = false;
  230   
  231       /**
  232        * The background thread.
  233        */
  234       protected Thread thread = null;
  235   
  236   
  237       /**
  238        * Coyote Protocol handler class name.
  239        * Defaults to the Coyote HTTP/1.1 protocolHandler.
  240        */
  241       protected String protocolHandlerClassName =
  242           "org.apache.coyote.http11.Http11Protocol";
  243   
  244   
  245       /**
  246        * Coyote protocol handler.
  247        */
  248       protected ProtocolHandler protocolHandler = null;
  249   
  250   
  251       /**
  252        * Coyote adapter.
  253        */
  254       protected Adapter adapter = null;
  255   
  256   
  257        /**
  258         * Mapper.
  259         */
  260        protected Mapper mapper = new Mapper();
  261   
  262   
  263        /**
  264         * Mapper listener.
  265         */
  266        protected MapperListener mapperListener = new MapperListener(mapper);
  267   
  268   
  269        /**
  270         * URI encoding.
  271         */
  272        protected String URIEncoding = null;
  273   
  274   
  275        /**
  276         * URI encoding as body.
  277         */
  278        protected boolean useBodyEncodingForURI = false;
  279   
  280   
  281        protected static HashMap replacements = new HashMap();
  282        static {
  283            replacements.put("acceptCount", "backlog");
  284            replacements.put("connectionLinger", "soLinger");
  285            replacements.put("connectionTimeout", "soTimeout");
  286            replacements.put("connectionUploadTimeout", "timeout");
  287            replacements.put("clientAuth", "clientauth");
  288            replacements.put("keystoreFile", "keystore");
  289            replacements.put("randomFile", "randomfile");
  290            replacements.put("rootFile", "rootfile");
  291            replacements.put("keystorePass", "keypass");
  292            replacements.put("keystoreType", "keytype");
  293            replacements.put("sslProtocol", "protocol");
  294            replacements.put("sslProtocols", "protocols");
  295        }
  296   
  297   
  298       // ------------------------------------------------------------- Properties
  299   
  300   
  301       /**
  302        * Return a configured property.
  303        */
  304       public Object getProperty(String name) {
  305           String repl = name;
  306           if (replacements.get(name) != null) {
  307               repl = (String) replacements.get(name);
  308           }
  309           return IntrospectionUtils.getProperty(protocolHandler, repl);
  310       }
  311   
  312   
  313       /**
  314        * Set a configured property.
  315        */
  316       public boolean setProperty(String name, String value) {
  317           String repl = name;
  318           if (replacements.get(name) != null) {
  319               repl = (String) replacements.get(name);
  320           }
  321           return IntrospectionUtils.setProperty(protocolHandler, repl, value);
  322       }
  323   
  324       /**
  325        * Return a configured property.
  326        */
  327       public Object getAttribute(String name) {
  328           return getProperty(name);
  329       }
  330   
  331   
  332       /**
  333        * Set a configured property.
  334        */
  335       public void setAttribute(String name, Object value) {
  336           setProperty(name, String.valueOf(value));
  337       }
  338   
  339   
  340       /**
  341        * remove a configured property.
  342        */
  343       public void removeProperty(String name) {
  344           // FIXME !
  345           //protocolHandler.removeAttribute(name);
  346       }
  347   
  348   
  349       /**
  350        * Return the <code>Service</code> with which we are associated (if any).
  351        */
  352       public Service getService() {
  353   
  354           return (this.service);
  355   
  356       }
  357   
  358   
  359       /**
  360        * Set the <code>Service</code> with which we are associated (if any).
  361        *
  362        * @param service The service that owns this Engine
  363        */
  364       public void setService(Service service) {
  365   
  366           this.service = service;
  367           // FIXME: setProperty("service", service);
  368   
  369       }
  370   
  371   
  372       /**
  373        * True if the TRACE method is allowed.  Default value is "false".
  374        */
  375       public boolean getAllowTrace() {
  376   
  377           return (this.allowTrace);
  378   
  379       }
  380   
  381   
  382       /**
  383        * Set the allowTrace flag, to disable or enable the TRACE HTTP method.
  384        *
  385        * @param allowTrace The new allowTrace flag
  386        */
  387       public void setAllowTrace(boolean allowTrace) {
  388   
  389           this.allowTrace = allowTrace;
  390           setProperty("allowTrace", String.valueOf(allowTrace));
  391   
  392       }
  393   
  394       /**
  395        * Is this connector available for processing requests?
  396        */
  397       public boolean isAvailable() {
  398   
  399           return (started);
  400   
  401       }
  402   
  403   
  404       /**
  405        * Return the input buffer size for this Connector.
  406        *
  407        * @deprecated
  408        */
  409       public int getBufferSize() {
  410           return 2048;
  411       }
  412   
  413       /**
  414        * Set the input buffer size for this Connector.
  415        *
  416        * @param bufferSize The new input buffer size.
  417        * @deprecated
  418        */
  419       public void setBufferSize(int bufferSize) {
  420       }
  421   
  422   
  423       /**
  424        * Return the Container used for processing requests received by this
  425        * Connector.
  426        */
  427       public Container getContainer() {
  428           if( container==null ) {
  429               // Lazy - maybe it was added later
  430               findContainer();
  431           }
  432           return (container);
  433   
  434       }
  435   
  436   
  437       /**
  438        * Set the Container used for processing requests received by this
  439        * Connector.
  440        *
  441        * @param container The new Container to use
  442        */
  443       public void setContainer(Container container) {
  444   
  445           this.container = container;
  446   
  447       }
  448   
  449   
  450       /**
  451        * Return the "empty session path" flag.
  452        */
  453       public boolean getEmptySessionPath() {
  454   
  455           return (this.emptySessionPath);
  456   
  457       }
  458   
  459   
  460       /**
  461        * Set the "empty session path" flag.
  462        *
  463        * @param emptySessionPath The new "empty session path" flag value
  464        */
  465       public void setEmptySessionPath(boolean emptySessionPath) {
  466   
  467           this.emptySessionPath = emptySessionPath;
  468           setProperty("emptySessionPath", String.valueOf(emptySessionPath));
  469   
  470       }
  471   
  472   
  473       /**
  474        * Return the "enable DNS lookups" flag.
  475        */
  476       public boolean getEnableLookups() {
  477   
  478           return (this.enableLookups);
  479   
  480       }
  481   
  482   
  483       /**
  484        * Set the "enable DNS lookups" flag.
  485        *
  486        * @param enableLookups The new "enable DNS lookups" flag value
  487        */
  488       public void setEnableLookups(boolean enableLookups) {
  489   
  490           this.enableLookups = enableLookups;
  491           setProperty("enableLookups", String.valueOf(enableLookups));
  492   
  493       }
  494   
  495   
  496       /**
  497        * Return descriptive information about this Connector implementation.
  498        */
  499       public String getInfo() {
  500   
  501           return (info);
  502   
  503       }
  504   
  505   
  506        /**
  507         * Return the mapper.
  508         */
  509        public Mapper getMapper() {
  510   
  511            return (mapper);
  512   
  513        }
  514   
  515   
  516       /**
  517        * Return the maximum size of a POST which will be automatically
  518        * parsed by the container.
  519        */
  520       public int getMaxPostSize() {
  521   
  522           return (maxPostSize);
  523   
  524       }
  525   
  526   
  527       /**
  528        * Set the maximum size of a POST which will be automatically
  529        * parsed by the container.
  530        *
  531        * @param maxPostSize The new maximum size in bytes of a POST which will
  532        * be automatically parsed by the container
  533        */
  534       public void setMaxPostSize(int maxPostSize) {
  535   
  536           this.maxPostSize = maxPostSize;
  537       }
  538   
  539   
  540       /**
  541        * Return the maximum size of a POST which will be saved by the container
  542        * during authentication.
  543        */
  544       public int getMaxSavePostSize() {
  545   
  546           return (maxSavePostSize);
  547   
  548       }
  549   
  550   
  551       /**
  552        * Set the maximum size of a POST which will be saved by the container
  553        * during authentication.
  554        *
  555        * @param maxSavePostSize The new maximum size in bytes of a POST which will
  556        * be saved by the container during authentication.
  557        */
  558       public void setMaxSavePostSize(int maxSavePostSize) {
  559   
  560           this.maxSavePostSize = maxSavePostSize;
  561           setProperty("maxSavePostSize", String.valueOf(maxSavePostSize));
  562       }
  563   
  564   
  565       /**
  566        * Return the port number on which we listen for requests.
  567        */
  568       public int getPort() {
  569   
  570           return (this.port);
  571   
  572       }
  573   
  574   
  575       /**
  576        * Set the port number on which we listen for requests.
  577        *
  578        * @param port The new port number
  579        */
  580       public void setPort(int port) {
  581   
  582           this.port = port;
  583           setProperty("port", String.valueOf(port));
  584   
  585       }
  586   
  587   
  588       /**
  589        * Return the Coyote protocol handler in use.
  590        */
  591       public String getProtocol() {
  592   
  593           if ("org.apache.coyote.http11.Http11Protocol".equals
  594               (getProtocolHandlerClassName())
  595               || "org.apache.coyote.http11.Http11AprProtocol".equals
  596               (getProtocolHandlerClassName())) {
  597               return "HTTP/1.1";
  598           } else if ("org.apache.jk.server.JkCoyoteHandler".equals
  599                      (getProtocolHandlerClassName())
  600                      || "org.apache.coyote.ajp.AjpAprProtocol".equals
  601                      (getProtocolHandlerClassName())) {
  602               return "AJP/1.3";
  603           }
  604           return getProtocolHandlerClassName();
  605   
  606       }
  607       
  608       // ---------------------------------------------- APR Version Constants
  609   
  610       private static final int TCN_REQUIRED_MAJOR = 1;
  611       private static final int TCN_REQUIRED_MINOR = 1;
  612       private static final int TCN_REQUIRED_PATCH = 3;
  613       private static boolean aprInitialized = false;
  614   
  615       // APR init support
  616       private static synchronized void initializeAPR()
  617       {
  618           if (aprInitialized) {
  619               return;
  620           }
  621           int major = 0;
  622           int minor = 0;
  623           int patch = 0;
  624           try {
  625               String methodName = "initialize";
  626               Class paramTypes[] = new Class[1];
  627               paramTypes[0] = String.class;
  628               Object paramValues[] = new Object[1];
  629               paramValues[0] = null;
  630               Class clazz = Class.forName("org.apache.tomcat.jni.Library");
  631               Method method = clazz.getMethod(methodName, paramTypes);
  632               method.invoke(null, paramValues);
  633               major = clazz.getField("TCN_MAJOR_VERSION").getInt(null);
  634               minor = clazz.getField("TCN_MINOR_VERSION").getInt(null);
  635               patch = clazz.getField("TCN_PATCH_VERSION").getInt(null);
  636           } catch (Throwable t) {
  637               return;
  638           }
  639           if ((major != TCN_REQUIRED_MAJOR) ||
  640               (minor != TCN_REQUIRED_MINOR) ||
  641               (patch <  TCN_REQUIRED_PATCH)) {
  642               try {
  643                   // Terminate the APR in case the version
  644                   // is below required.
  645                   String methodName = "terminate";
  646                   Method method = Class.forName("org.apache.tomcat.jni.Library")
  647                                       .getMethod(methodName, (Class [])null);
  648                   method.invoke(null, (Object []) null);
  649               } catch (Throwable t) {
  650                   // Ignore
  651               }
  652               return;
  653           }
  654           aprInitialized = true;
  655       }
  656   
  657       /**
  658        * Set the Coyote protocol which will be used by the connector.
  659        *
  660        * @param protocol The Coyote protocol name
  661        */
  662       public void setProtocol(String protocol) {
  663   
  664           // Test APR support
  665           initializeAPR();
  666   
  667           if (aprInitialized) {
  668               if ("HTTP/1.1".equals(protocol)) {
  669                   setProtocolHandlerClassName
  670                       ("org.apache.coyote.http11.Http11AprProtocol");
  671               } else if ("AJP/1.3".equals(protocol)) {
  672                   setProtocolHandlerClassName
  673                       ("org.apache.coyote.ajp.AjpAprProtocol");
  674               } else if (protocol != null) {
  675                   setProtocolHandlerClassName(protocol);
  676               } else {
  677                   setProtocolHandlerClassName
  678                       ("org.apache.coyote.http11.Http11AprProtocol");
  679               }
  680           } else {
  681               if ("HTTP/1.1".equals(protocol)) {
  682                   setProtocolHandlerClassName
  683                       ("org.apache.coyote.http11.Http11Protocol");
  684               } else if ("AJP/1.3".equals(protocol)) {
  685                   setProtocolHandlerClassName
  686                       ("org.apache.jk.server.JkCoyoteHandler");
  687               } else if (protocol != null) {
  688                   setProtocolHandlerClassName(protocol);
  689               }
  690           }
  691   
  692       }
  693   
  694   
  695       /**
  696        * Return the class name of the Coyote protocol handler in use.
  697        */
  698       public String getProtocolHandlerClassName() {
  699   
  700           return (this.protocolHandlerClassName);
  701   
  702       }
  703   
  704   
  705       /**
  706        * Set the class name of the Coyote protocol handler which will be used
  707        * by the connector.
  708        *
  709        * @param protocolHandlerClassName The new class name
  710        */
  711       public void setProtocolHandlerClassName(String protocolHandlerClassName) {
  712   
  713           this.protocolHandlerClassName = protocolHandlerClassName;
  714   
  715       }
  716   
  717   
  718       /**
  719        * Return the protocol handler associated with the connector.
  720        */
  721       public ProtocolHandler getProtocolHandler() {
  722   
  723           return (this.protocolHandler);
  724   
  725       }
  726   
  727   
  728       /**
  729        * Return the proxy server name for this Connector.
  730        */
  731       public String getProxyName() {
  732   
  733           return (this.proxyName);
  734   
  735       }
  736   
  737   
  738       /**
  739        * Set the proxy server name for this Connector.
  740        *
  741        * @param proxyName The new proxy server name
  742        */
  743       public void setProxyName(String proxyName) {
  744   
  745           if(proxyName != null && proxyName.length() > 0) {
  746               this.proxyName = proxyName;
  747               setProperty("proxyName", proxyName);
  748           } else {
  749               this.proxyName = null;
  750               removeProperty("proxyName");
  751           }
  752   
  753       }
  754   
  755   
  756       /**
  757        * Return the proxy server port for this Connector.
  758        */
  759       public int getProxyPort() {
  760   
  761           return (this.proxyPort);
  762   
  763       }
  764   
  765   
  766       /**
  767        * Set the proxy server port for this Connector.
  768        *
  769        * @param proxyPort The new proxy server port
  770        */
  771       public void setProxyPort(int proxyPort) {
  772   
  773           this.proxyPort = proxyPort;
  774           setProperty("proxyPort", String.valueOf(proxyPort));
  775   
  776       }
  777   
  778   
  779       /**
  780        * Return the port number to which a request should be redirected if
  781        * it comes in on a non-SSL port and is subject to a security constraint
  782        * with a transport guarantee that requires SSL.
  783        */
  784       public int getRedirectPort() {
  785   
  786           return (this.redirectPort);
  787   
  788       }
  789   
  790   
  791       /**
  792        * Set the redirect port number.
  793        *
  794        * @param redirectPort The redirect port number (non-SSL to SSL)
  795        */
  796       public void setRedirectPort(int redirectPort) {
  797   
  798           this.redirectPort = redirectPort;
  799           setProperty("redirectPort", String.valueOf(redirectPort));
  800   
  801       }
  802   
  803   
  804       /**
  805        * Return the scheme that will be assigned to requests received
  806        * through this connector.  Default value is "http".
  807        */
  808       public String getScheme() {
  809   
  810           return (this.scheme);
  811   
  812       }
  813   
  814   
  815       /**
  816        * Set the scheme that will be assigned to requests received through
  817        * this connector.
  818        *
  819        * @param scheme The new scheme
  820        */
  821       public void setScheme(String scheme) {
  822   
  823           this.scheme = scheme;
  824   
  825       }
  826   
  827   
  828       /**
  829        * Return the secure connection flag that will be assigned to requests
  830        * received through this connector.  Default value is "false".
  831        */
  832       public boolean getSecure() {
  833   
  834           return (this.secure);
  835   
  836       }
  837   
  838   
  839       /**
  840        * Set the secure connection flag that will be assigned to requests
  841        * received through this connector.
  842        *
  843        * @param secure The new secure connection flag
  844        */
  845       public void setSecure(boolean secure) {
  846   
  847           this.secure = secure;
  848           setProperty("secure", Boolean.toString(secure));
  849       }
  850   
  851        /**
  852         * Return the character encoding to be used for the URI.
  853         */
  854        public String getURIEncoding() {
  855   
  856            return (this.URIEncoding);
  857   
  858        }
  859   
  860   
  861        /**
  862         * Set the URI encoding to be used for the URI.
  863         *
  864         * @param URIEncoding The new URI character encoding.
  865         */
  866        public void setURIEncoding(String URIEncoding) {
  867   
  868            this.URIEncoding = URIEncoding;
  869            setProperty("uRIEncoding", URIEncoding);
  870   
  871        }
  872   
  873   
  874        /**
  875         * Return the true if the entity body encoding should be used for the URI.
  876         */
  877        public boolean getUseBodyEncodingForURI() {
  878   
  879            return (this.useBodyEncodingForURI);
  880   
  881        }
  882   
  883   
  884        /**
  885         * Set if the entity body encoding should be used for the URI.
  886         *
  887         * @param useBodyEncodingForURI The new value for the flag.
  888         */
  889        public void setUseBodyEncodingForURI(boolean useBodyEncodingForURI) {
  890   
  891            this.useBodyEncodingForURI = useBodyEncodingForURI;
  892            setProperty
  893                ("useBodyEncodingForURI", String.valueOf(useBodyEncodingForURI));
  894   
  895        }
  896   
  897   
  898       /**
  899        * Indicates whether the generation of an X-Powered-By response header for
  900        * servlet-generated responses is enabled or disabled for this Connector.
  901        *
  902        * @return true if generation of X-Powered-By response header is enabled,
  903        * false otherwise
  904        */
  905       public boolean getXpoweredBy() {
  906           return xpoweredBy;
  907       }
  908   
  909   
  910       /**
  911        * Enables or disables the generation of an X-Powered-By header (with value
  912        * Servlet/2.5) for all servlet-generated responses returned by this
  913        * Connector.
  914        *
  915        * @param xpoweredBy true if generation of X-Powered-By response header is
  916        * to be enabled, false otherwise
  917        */
  918       public void setXpoweredBy(boolean xpoweredBy) {
  919           this.xpoweredBy = xpoweredBy;
  920           setProperty("xpoweredBy", String.valueOf(xpoweredBy));
  921       }
  922   
  923       /**
  924        * Enable the use of IP-based virtual hosting.
  925        *
  926        * @param useIPVHosts <code>true</code> if Hosts are identified by IP,
  927        *                    <code>false/code> if Hosts are identified by name.
  928        */
  929       public void setUseIPVHosts(boolean useIPVHosts) {
  930           this.useIPVHosts = useIPVHosts;
  931           setProperty("useIPVHosts", String.valueOf(useIPVHosts));
  932       }
  933   
  934       /**
  935        * Test if IP-based virtual hosting is enabled.
  936        */
  937       public boolean getUseIPVHosts() {
  938           return useIPVHosts;
  939       }
  940   
  941       // --------------------------------------------------------- Public Methods
  942   
  943   
  944       /**
  945        * Create (or allocate) and return a Request object suitable for
  946        * specifying the contents of a Request to the responsible Container.
  947        */
  948       public Request createRequest() {
  949   
  950           Request request = new Request();
  951           request.setConnector(this);
  952           return (request);
  953   
  954       }
  955   
  956   
  957       /**
  958        * Create (or allocate) and return a Response object suitable for
  959        * receiving the contents of a Response from the responsible Container.
  960        */
  961       public Response createResponse() {
  962   
  963           Response response = new Response();
  964           response.setConnector(this);
  965           return (response);
  966   
  967       }
  968   
  969   
  970       // ------------------------------------------------------ Lifecycle Methods
  971   
  972   
  973       /**
  974        * Add a lifecycle event listener to this component.
  975        *
  976        * @param listener The listener to add
  977        */
  978       public void addLifecycleListener(LifecycleListener listener) {
  979   
  980           lifecycle.addLifecycleListener(listener);
  981   
  982       }
  983   
  984   
  985       /**
  986        * Get the lifecycle listeners associated with this lifecycle. If this
  987        * Lifecycle has no listeners registered, a zero-length array is returned.
  988        */
  989       public LifecycleListener[] findLifecycleListeners() {
  990   
  991           return lifecycle.findLifecycleListeners();
  992   
  993       }
  994   
  995   
  996       /**
  997        * Remove a lifecycle event listener from this component.
  998        *
  999        * @param listener The listener to add
 1000        */
 1001       public void removeLifecycleListener(LifecycleListener listener) {
 1002   
 1003           lifecycle.removeLifecycleListener(listener);
 1004   
 1005       }
 1006   
 1007   
 1008       protected ObjectName createObjectName(String domain, String type)
 1009               throws MalformedObjectNameException {
 1010           String encodedAddr = null;
 1011           if (getProperty("address") != null) {
 1012               encodedAddr = URLEncoder.encode(getProperty("address").toString());
 1013           }
 1014           String addSuffix = (getProperty("address") == null) ? "" : ",address="
 1015                   + encodedAddr;
 1016           ObjectName _oname = new ObjectName(domain + ":type=" + type + ",port="
 1017                   + getPort() + addSuffix);
 1018           return _oname;
 1019       }
 1020   
 1021       /**
 1022        * Initialize this connector (create ServerSocket here!)
 1023        */
 1024       public void initialize()
 1025           throws LifecycleException
 1026       {
 1027           if (initialized) {
 1028               if(log.isInfoEnabled())
 1029                   log.info(sm.getString("coyoteConnector.alreadyInitialized"));
 1030              return;
 1031           }
 1032   
 1033           this.initialized = true;
 1034   
 1035           if( oname == null && (container instanceof StandardEngine)) {
 1036               try {
 1037                   // we are loaded directly, via API - and no name was given to us
 1038                   StandardEngine cb=(StandardEngine)container;
 1039                   oname = createObjectName(cb.getName(), "Connector");
 1040                   Registry.getRegistry(null, null)
 1041                       .registerComponent(this, oname, null);
 1042                   controller=oname;
 1043               } catch (Exception e) {
 1044                   log.error( "Error registering connector ", e);
 1045               }
 1046               if(log.isDebugEnabled())
 1047                   log.debug("Creating name for connector " + oname);
 1048           }
 1049   
 1050           // Initializa adapter
 1051           adapter = new CoyoteAdapter(this);
 1052           protocolHandler.setAdapter(adapter);
 1053   
 1054           IntrospectionUtils.setProperty(protocolHandler, "jkHome",
 1055                                          System.getProperty("catalina.base"));
 1056   
 1057           try {
 1058               protocolHandler.init();
 1059           } catch (Exception e) {
 1060               throw new LifecycleException
 1061                   (sm.getString
 1062                    ("coyoteConnector.protocolHandlerInitializationFailed", e));
 1063           }
 1064       }
 1065   
 1066   
 1067       /**
 1068        * Pause the connector.
 1069        */
 1070       public void pause()
 1071           throws LifecycleException {
 1072           try {
 1073               protocolHandler.pause();
 1074           } catch (Exception e) {
 1075               log.error(sm.getString
 1076                         ("coyoteConnector.protocolHandlerPauseFailed"), e);
 1077           }
 1078       }
 1079   
 1080   
 1081       /**
 1082        * Pause the connector.
 1083        */
 1084       public void resume()
 1085           throws LifecycleException {
 1086           try {
 1087               protocolHandler.resume();
 1088           } catch (Exception e) {
 1089               log.error(sm.getString
 1090                         ("coyoteConnector.protocolHandlerResumeFailed"), e);
 1091           }
 1092       }
 1093   
 1094   
 1095       /**
 1096        * Begin processing requests via this Connector.
 1097        *
 1098        * @exception LifecycleException if a fatal startup error occurs
 1099        */
 1100       public void start() throws LifecycleException {
 1101           if( !initialized )
 1102               initialize();
 1103   
 1104           // Validate and update our current state
 1105           if (started ) {
 1106               if(log.isInfoEnabled())
 1107                   log.info(sm.getString("coyoteConnector.alreadyStarted"));
 1108               return;
 1109           }
 1110           lifecycle.fireLifecycleEvent(START_EVENT, null);
 1111           started = true;
 1112   
 1113           // We can't register earlier - the JMX registration of this happens
 1114           // in Server.start callback
 1115           if ( this.oname != null ) {
 1116               // We are registred - register the adapter as well.
 1117               try {
 1118                   Registry.getRegistry(null, null).registerComponent
 1119                       (protocolHandler, createObjectName(this.domain,"ProtocolHandler"), null);
 1120               } catch (Exception ex) {
 1121                   log.error(sm.getString
 1122                             ("coyoteConnector.protocolRegistrationFailed"), ex);
 1123               }
 1124           } else {
 1125               if(log.isInfoEnabled())
 1126                   log.info(sm.getString
 1127                        ("coyoteConnector.cannotRegisterProtocol"));
 1128           }
 1129   
 1130           try {
 1131               protocolHandler.start();
 1132           } catch (Exception e) {
 1133               String errPrefix = "";
 1134               if(this.service != null) {
 1135                   errPrefix += "service.getName(): \"" + this.service.getName() + "\"; ";
 1136               }
 1137   
 1138               throw new LifecycleException
 1139                   (errPrefix + " " + sm.getString
 1140                    ("coyoteConnector.protocolHandlerStartFailed", e));
 1141           }
 1142   
 1143           if( this.domain != null ) {
 1144               mapperListener.setDomain( domain );
 1145               //mapperListener.setEngine( service.getContainer().getName() );
 1146               mapperListener.init();
 1147               try {
 1148                   ObjectName mapperOname = createObjectName(this.domain,"Mapper");
 1149                   if (log.isDebugEnabled())
 1150                       log.debug(sm.getString(
 1151                               "coyoteConnector.MapperRegistration", mapperOname));
 1152                   Registry.getRegistry(null, null).registerComponent
 1153                       (mapper, mapperOname, "Mapper");
 1154               } catch (Exception ex) {
 1155                   log.error(sm.getString
 1156                           ("coyoteConnector.protocolRegistrationFailed"), ex);
 1157               }
 1158           }
 1159       }
 1160   
 1161   
 1162       /**
 1163        * Terminate processing requests via this Connector.
 1164        *
 1165        * @exception LifecycleException if a fatal shutdown error occurs
 1166        */
 1167       public void stop() throws LifecycleException {
 1168   
 1169           // Validate and update our current state
 1170           if (!started) {
 1171               log.error(sm.getString("coyoteConnector.notStarted"));
 1172               return;
 1173   
 1174           }
 1175           lifecycle.fireLifecycleEvent(STOP_EVENT, null);
 1176           started = false;
 1177   
 1178           try {
 1179               mapperListener.destroy();
 1180               Registry.getRegistry(null, null).unregisterComponent
 1181                   (createObjectName(this.domain,"Mapper"));
 1182               Registry.getRegistry(null, null).unregisterComponent
 1183                   (createObjectName(this.domain,"ProtocolHandler"));
 1184           } catch (MalformedObjectNameException e) {
 1185               log.error( sm.getString
 1186                       ("coyoteConnector.protocolUnregistrationFailed"), e);
 1187           }
 1188           try {
 1189               protocolHandler.destroy();
 1190           } catch (Exception e) {
 1191               throw new LifecycleException
 1192                   (sm.getString
 1193                    ("coyoteConnector.protocolHandlerDestroyFailed", e));
 1194           }
 1195   
 1196       }
 1197   
 1198   
 1199       // -------------------- JMX registration  --------------------
 1200       protected String domain;
 1201       protected ObjectName oname;
 1202       protected MBeanServer mserver;
 1203       ObjectName controller;
 1204   
 1205       public ObjectName getController() {
 1206           return controller;
 1207       }
 1208   
 1209       public void setController(ObjectName controller) {
 1210           this.controller = controller;
 1211       }
 1212   
 1213       public ObjectName getObjectName() {
 1214           return oname;
 1215       }
 1216   
 1217       public String getDomain() {
 1218           return domain;
 1219       }
 1220   
 1221       public ObjectName preRegister(MBeanServer server,
 1222                                     ObjectName name) throws Exception {
 1223           oname=name;
 1224           mserver=server;
 1225           domain=name.getDomain();
 1226           return name;
 1227       }
 1228   
 1229       public void postRegister(Boolean registrationDone) {
 1230       }
 1231   
 1232       public void preDeregister() throws Exception {
 1233       }
 1234   
 1235       public void postDeregister() {
 1236           try {
 1237               if( started ) {
 1238                   stop();
 1239               }
 1240           } catch( Throwable t ) {
 1241               log.error( "Unregistering - can't stop", t);
 1242           }
 1243       }
 1244   
 1245       protected void findContainer() {
 1246           try {
 1247               // Register to the service
 1248               ObjectName parentName=new ObjectName( domain + ":" +
 1249                       "type=Service");
 1250   
 1251               if(log.isDebugEnabled())
 1252                   log.debug("Adding to " + parentName );
 1253               if( mserver.isRegistered(parentName )) {
 1254                   mserver.invoke(parentName, "addConnector", new Object[] { this },
 1255                           new String[] {"org.apache.catalina.connector.Connector"});
 1256                   // As a side effect we'll get the container field set
 1257                   // Also initialize will be called
 1258                   //return;
 1259               }
 1260               // XXX Go directly to the Engine
 1261               // initialize(); - is called by addConnector
 1262               ObjectName engName=new ObjectName( domain + ":" + "type=Engine");
 1263               if( mserver.isRegistered(engName )) {
 1264                   Object obj=mserver.getAttribute(engName, "managedResource");
 1265                   if(log.isDebugEnabled())
 1266                         log.debug("Found engine " + obj + " " + obj.getClass());
 1267                   container=(Container)obj;
 1268   
 1269                   // Internal initialize - we now have the Engine
 1270                   initialize();
 1271   
 1272                   if(log.isDebugEnabled())
 1273                       log.debug("Initialized");
 1274                   // As a side effect we'll get the container field set
 1275                   // Also initialize will be called
 1276                   return;
 1277               }
 1278           } catch( Exception ex ) {
 1279               log.error( "Error finding container " + ex);
 1280           }
 1281       }
 1282   
 1283       public void init() throws Exception {
 1284   
 1285           if( this.getService() != null ) {
 1286               if(log.isDebugEnabled())
 1287                    log.debug( "Already configured" );
 1288               return;
 1289           }
 1290           if( container==null ) {
 1291               findContainer();
 1292           }
 1293       }
 1294   
 1295       public void destroy() throws Exception {
 1296           if( oname!=null && controller==oname ) {
 1297               if(log.isDebugEnabled())
 1298                    log.debug("Unregister itself " + oname );
 1299               Registry.getRegistry(null, null).unregisterComponent(oname);
 1300           }
 1301           if( getService() == null)
 1302               return;
 1303           getService().removeConnector(this);
 1304       }
 1305   
 1306   }

Save This Page
Home » apache-tomcat-6.0.16-src » org.apache » catalina » connector » [javadoc | source]