0001: /*
0002: * Copyright 1999,2004 The Apache Software Foundation.
0003: *
0004: * Licensed under the Apache License, Version 2.0 (the "License");
0005: * you may not use this file except in compliance with the License.
0006: * You may obtain a copy of the License at
0007: *
0008: * http://www.apache.org/licenses/LICENSE-2.0
0009: *
0010: * Unless required by applicable law or agreed to in writing, software
0011: * distributed under the License is distributed on an "AS IS" BASIS,
0012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013: * See the License for the specific language governing permissions and
0014: * limitations under the License.
0015: */
0016:
0017: package org.apache.coyote.tomcat5;
0018:
0019: import java.net.URLEncoder;
0020: import java.util.HashMap;
0021: import java.util.Iterator;
0022:
0023: import javax.management.MBeanRegistration;
0024: import javax.management.MBeanServer;
0025: import javax.management.MalformedObjectNameException;
0026: import javax.management.ObjectName;
0027:
0028: import org.apache.catalina.Connector;
0029: import org.apache.catalina.Container;
0030: import org.apache.catalina.Lifecycle;
0031: import org.apache.catalina.LifecycleException;
0032: import org.apache.catalina.LifecycleListener;
0033: import org.apache.catalina.Logger;
0034: import org.apache.catalina.Request;
0035: import org.apache.catalina.Response;
0036: import org.apache.catalina.Service;
0037: import org.apache.catalina.core.StandardEngine;
0038: import org.apache.catalina.net.ServerSocketFactory;
0039: import org.apache.catalina.util.LifecycleSupport;
0040: import org.apache.catalina.util.StringManager;
0041: import org.apache.commons.logging.Log;
0042: import org.apache.commons.logging.LogFactory;
0043: import org.apache.commons.modeler.Registry;
0044: import org.apache.coyote.Adapter;
0045: import org.apache.coyote.ProtocolHandler;
0046: import org.apache.tomcat.util.IntrospectionUtils;
0047: import org.apache.tomcat.util.http.mapper.Mapper;
0048:
0049: /**
0050: * Implementation of a Coyote connector for Tomcat 5.x.
0051: *
0052: * @author Craig R. McClanahan
0053: * @author Remy Maucherat
0054: * @version $Revision: 1.43 $ $Date: 2004/05/27 16:09:48 $
0055: */
0056:
0057: public class CoyoteConnector implements Connector, Lifecycle,
0058: MBeanRegistration {
0059: private static Log log = LogFactory.getLog(CoyoteConnector.class);
0060:
0061: // ----------------------------------------------------- Instance Variables
0062:
0063: /**
0064: * Holder for our configured properties.
0065: */
0066: private HashMap properties = new HashMap();
0067:
0068: /**
0069: * The <code>Service</code> we are associated with (if any).
0070: */
0071: private Service service = null;
0072:
0073: /**
0074: * The accept count for this Connector.
0075: */
0076: private int acceptCount = 10;
0077:
0078: /**
0079: * The IP address on which to bind, if any. If <code>null</code>, all
0080: * addresses on the server will be bound.
0081: */
0082: private String address = null;
0083:
0084: /**
0085: * Do we allow TRACE ?
0086: */
0087: private boolean allowTrace = false;
0088:
0089: /**
0090: * The input buffer size we should create on input streams.
0091: */
0092: private int bufferSize = 2048;
0093:
0094: /**
0095: * The Container used for processing requests received by this Connector.
0096: */
0097: protected Container container = null;
0098:
0099: /**
0100: * Compression value.
0101: */
0102: private String compression = "off";
0103:
0104: /**
0105: * The debugging detail level for this component.
0106: */
0107: private int debug = 0;
0108:
0109: /**
0110: * The "enable DNS lookups" flag for this Connector.
0111: */
0112: private boolean enableLookups = false;
0113:
0114: /**
0115: * The server socket factory for this component.
0116: */
0117: private ServerSocketFactory factory = null;
0118:
0119: /*
0120: * Is generation of X-Powered-By response header enabled/disabled?
0121: */
0122: private boolean xpoweredBy;
0123:
0124: /**
0125: * Descriptive information about this Connector implementation.
0126: */
0127: private static final String info = "org.apache.coyote.tomcat5.CoyoteConnector/2.0";
0128:
0129: /**
0130: * The lifecycle event support for this component.
0131: */
0132: protected LifecycleSupport lifecycle = new LifecycleSupport(this );
0133:
0134: /**
0135: * The minimum number of processors to start at initialization time.
0136: */
0137: protected int minProcessors = 5;
0138:
0139: /**
0140: * The maximum number of processors allowed, or <0 for unlimited.
0141: */
0142: private int maxProcessors = 20;
0143:
0144: /**
0145: * The thread priority for processors.
0146: */
0147: private int threadPriority = Thread.NORM_PRIORITY;
0148:
0149: /**
0150: * Linger value on the incoming connection.
0151: * Note : a value inferior to 0 means no linger.
0152: */
0153: private int connectionLinger = Constants.DEFAULT_CONNECTION_LINGER;
0154:
0155: /**
0156: * Timeout value on the incoming connection.
0157: * Note : a value of 0 means no timeout.
0158: */
0159: private int connectionTimeout = Constants.DEFAULT_CONNECTION_TIMEOUT;
0160:
0161: /**
0162: * Timeout value on the incoming connection during request processing.
0163: * Note : a value of 0 means no timeout.
0164: */
0165: private int connectionUploadTimeout = Constants.DEFAULT_CONNECTION_UPLOAD_TIMEOUT;
0166:
0167: /**
0168: * Timeout value on the server socket.
0169: * Note : a value of 0 means no timeout.
0170: */
0171: private int serverSocketTimeout = Constants.DEFAULT_SERVER_SOCKET_TIMEOUT;
0172:
0173: /**
0174: * The port number on which we listen for requests.
0175: */
0176: private int port = 0;
0177:
0178: /**
0179: * The server name to which we should pretend requests to this Connector
0180: * were directed. This is useful when operating Tomcat behind a proxy
0181: * server, so that redirects get constructed accurately. If not specified,
0182: * the server name included in the <code>Host</code> header is used.
0183: */
0184: private String proxyName = null;
0185:
0186: /**
0187: * The server port to which we should pretent requests to this Connector
0188: * were directed. This is useful when operating Tomcat behind a proxy
0189: * server, so that redirects get constructed accurately. If not specified,
0190: * the port number specified by the <code>port</code> property is used.
0191: */
0192: private int proxyPort = 0;
0193:
0194: /**
0195: * The redirect port for non-SSL to SSL redirects.
0196: */
0197: private int redirectPort = 443;
0198:
0199: /**
0200: * The request scheme that will be set on all requests received
0201: * through this connector.
0202: */
0203: private String scheme = "http";
0204:
0205: /**
0206: * The secure connection flag that will be set on all requests received
0207: * through this connector.
0208: */
0209: private boolean secure = false;
0210:
0211: /** For jk, do tomcat authentication if true, trust server if false
0212: */
0213: private boolean tomcatAuthentication = true;
0214:
0215: /**
0216: * The string manager for this package.
0217: */
0218: private StringManager sm = StringManager
0219: .getManager(Constants.Package);
0220:
0221: /**
0222: * Flag to disable setting a seperate time-out for uploads.
0223: * If <code>true</code>, then the <code>timeout</code> parameter is
0224: * ignored. If <code>false</code>, then the <code>timeout</code>
0225: * parameter is used to control uploads.
0226: */
0227: private boolean disableUploadTimeout = false;
0228:
0229: /**
0230: * Maximum size of a HTTP header. 4KB is the default.
0231: */
0232: private int maxHttpHeaderSize = 4 * 1024;
0233:
0234: /**
0235: * Maximum number of Keep-Alive requests to honor per connection.
0236: */
0237: private int maxKeepAliveRequests = 100;
0238:
0239: /**
0240: * Maximum size of a POST which will be automatically parsed by the
0241: * container. 2MB by default.
0242: */
0243: private int maxPostSize = 2 * 1024 * 1024;
0244:
0245: /**
0246: * Has this component been initialized yet?
0247: */
0248: private boolean initialized = false;
0249:
0250: /**
0251: * Has this component been started yet?
0252: */
0253: private boolean started = false;
0254:
0255: /**
0256: * The shutdown signal to our background thread
0257: */
0258: private boolean stopped = false;
0259:
0260: /**
0261: * The background thread.
0262: */
0263: private Thread thread = null;
0264:
0265: /**
0266: * Use TCP no delay ?
0267: */
0268: private boolean tcpNoDelay = true;
0269:
0270: /**
0271: * Coyote Protocol handler class name.
0272: * Defaults to the Coyote HTTP/1.1 protocolHandler.
0273: */
0274: private String protocolHandlerClassName = "org.apache.coyote.http11.Http11Protocol";
0275:
0276: /**
0277: * Coyote protocol handler.
0278: */
0279: private ProtocolHandler protocolHandler = null;
0280:
0281: /**
0282: * Coyote adapter.
0283: */
0284: private Adapter adapter = null;
0285:
0286: /**
0287: * Mapper.
0288: */
0289: private Mapper mapper = new Mapper();
0290:
0291: /**
0292: * Mapper listener.
0293: */
0294: private MapperListener mapperListener = new MapperListener(mapper);
0295:
0296: /**
0297: * URI encoding.
0298: */
0299: private String URIEncoding = null;
0300:
0301: /**
0302: * URI encoding as body.
0303: */
0304: private boolean useBodyEncodingForURI = false;
0305:
0306: // ------------------------------------------------------------- Properties
0307:
0308: /**
0309: * Return a configured property.
0310: */
0311: public Object getProperty(String name) {
0312: return properties.get(name);
0313: }
0314:
0315: /**
0316: * Set a configured property.
0317: */
0318: public void setProperty(String name, Object value) {
0319: properties.put(name, value);
0320: }
0321:
0322: /**
0323: * remove a configured property.
0324: */
0325: public void removeProperty(String name) {
0326: properties.remove(name);
0327: }
0328:
0329: /**
0330: * Return the <code>Service</code> with which we are associated (if any).
0331: */
0332: public Service getService() {
0333:
0334: return (this .service);
0335:
0336: }
0337:
0338: /**
0339: * Set the <code>Service</code> with which we are associated (if any).
0340: *
0341: * @param service The service that owns this Engine
0342: */
0343: public void setService(Service service) {
0344:
0345: this .service = service;
0346: setProperty("service", service);
0347:
0348: }
0349:
0350: /**
0351: * Get the value of compression.
0352: */
0353: public String getCompression() {
0354:
0355: return (compression);
0356:
0357: }
0358:
0359: /**
0360: * Set the value of compression.
0361: *
0362: * @param compression The new compression value, which can be "on", "off"
0363: * or "force"
0364: */
0365: public void setCompression(String compression) {
0366:
0367: this .compression = compression;
0368: setProperty("compression", compression);
0369:
0370: }
0371:
0372: /**
0373: * Return the connection linger for this Connector.
0374: */
0375: public int getConnectionLinger() {
0376:
0377: return (connectionLinger);
0378:
0379: }
0380:
0381: /**
0382: * Set the connection linger for this Connector.
0383: *
0384: * @param count The new connection linge
0385: */
0386: public void setConnectionLinger(int connectionLinger) {
0387:
0388: this .connectionLinger = connectionLinger;
0389: setProperty("soLinger", String.valueOf(connectionLinger));
0390:
0391: }
0392:
0393: /**
0394: * Return the connection timeout for this Connector.
0395: */
0396: public int getConnectionTimeout() {
0397:
0398: return (connectionTimeout);
0399:
0400: }
0401:
0402: /**
0403: * Set the connection timeout for this Connector.
0404: *
0405: * @param count The new connection timeout
0406: */
0407: public void setConnectionTimeout(int connectionTimeout) {
0408:
0409: this .connectionTimeout = connectionTimeout;
0410: setProperty("soTimeout", String.valueOf(connectionTimeout));
0411:
0412: }
0413:
0414: /**
0415: * Return the connection upload timeout for this Connector.
0416: */
0417: public int getConnectionUploadTimeout() {
0418:
0419: return (connectionUploadTimeout);
0420:
0421: }
0422:
0423: /**
0424: * Set the connection upload timeout for this Connector.
0425: *
0426: * @param connectionUploadTimeout The new connection upload timeout
0427: */
0428: public void setConnectionUploadTimeout(int connectionUploadTimeout) {
0429:
0430: this .connectionUploadTimeout = connectionUploadTimeout;
0431: setProperty("timeout", String.valueOf(connectionUploadTimeout));
0432:
0433: }
0434:
0435: /**
0436: * Return the server socket timeout for this Connector.
0437: */
0438: public int getServerSocketTimeout() {
0439:
0440: return (serverSocketTimeout);
0441:
0442: }
0443:
0444: /**
0445: * Set the server socket timeout for this Connector.
0446: *
0447: * @param connectionUploadTimeout The new server socket timeout
0448: */
0449: public void setServerSocketTimeout(int serverSocketTimeout) {
0450:
0451: this .serverSocketTimeout = serverSocketTimeout;
0452: setProperty("serverSoTimeout", String
0453: .valueOf(serverSocketTimeout));
0454:
0455: }
0456:
0457: /**
0458: * Return the accept count for this Connector.
0459: */
0460: public int getAcceptCount() {
0461:
0462: return (acceptCount);
0463:
0464: }
0465:
0466: /**
0467: * Set the accept count for this Connector.
0468: *
0469: * @param count The new accept count
0470: */
0471: public void setAcceptCount(int count) {
0472:
0473: this .acceptCount = count;
0474: setProperty("backlog", String.valueOf(count));
0475:
0476: }
0477:
0478: /**
0479: * Return the bind IP address for this Connector.
0480: */
0481: public String getAddress() {
0482:
0483: return (this .address);
0484:
0485: }
0486:
0487: /**
0488: * Set the bind IP address for this Connector.
0489: *
0490: * @param address The bind IP address
0491: */
0492: public void setAddress(String address) {
0493:
0494: this .address = address;
0495: setProperty("address", address);
0496:
0497: }
0498:
0499: /**
0500: * True if the TRACE method is allowed. Default value is "false".
0501: */
0502: public boolean getAllowTrace() {
0503:
0504: return (this .allowTrace);
0505:
0506: }
0507:
0508: /**
0509: * Set the allowTrace flag, to disable or enable the TRACE HTTP method.
0510: *
0511: * @param allowTrace The new allowTrace flag
0512: */
0513: public void setAllowTrace(boolean allowTrace) {
0514:
0515: this .allowTrace = allowTrace;
0516: setProperty("allowTrace", String.valueOf(allowTrace));
0517:
0518: }
0519:
0520: /**
0521: * Is this connector available for processing requests?
0522: */
0523: public boolean isAvailable() {
0524:
0525: return (started);
0526:
0527: }
0528:
0529: /**
0530: * Return the input buffer size for this Connector.
0531: */
0532: public int getBufferSize() {
0533:
0534: return (this .bufferSize);
0535:
0536: }
0537:
0538: /**
0539: * Set the input buffer size for this Connector.
0540: *
0541: * @param bufferSize The new input buffer size.
0542: */
0543: public void setBufferSize(int bufferSize) {
0544:
0545: this .bufferSize = bufferSize;
0546: setProperty("bufferSize", String.valueOf(bufferSize));
0547:
0548: }
0549:
0550: /**
0551: * Return the Container used for processing requests received by this
0552: * Connector.
0553: */
0554: public Container getContainer() {
0555: if (container == null) {
0556: // Lazy - maybe it was added later
0557: findContainer();
0558: }
0559: return (container);
0560:
0561: }
0562:
0563: /**
0564: * Set the Container used for processing requests received by this
0565: * Connector.
0566: *
0567: * @param container The new Container to use
0568: */
0569: public void setContainer(Container container) {
0570:
0571: this .container = container;
0572:
0573: }
0574:
0575: /**
0576: * Return the debugging detail level for this component.
0577: */
0578: public int getDebug() {
0579:
0580: return (debug);
0581:
0582: }
0583:
0584: /**
0585: * Set the debugging detail level for this component.
0586: *
0587: * @param debug The new debugging detail level
0588: */
0589: public void setDebug(int debug) {
0590:
0591: this .debug = debug;
0592:
0593: }
0594:
0595: /**
0596: * Return the "enable DNS lookups" flag.
0597: */
0598: public boolean getEnableLookups() {
0599:
0600: return (this .enableLookups);
0601:
0602: }
0603:
0604: /**
0605: * Set the "enable DNS lookups" flag.
0606: *
0607: * @param enableLookups The new "enable DNS lookups" flag value
0608: */
0609: public void setEnableLookups(boolean enableLookups) {
0610:
0611: this .enableLookups = enableLookups;
0612: setProperty("enableLookups", String.valueOf(enableLookups));
0613:
0614: }
0615:
0616: /**
0617: * Return the server socket factory used by this Container.
0618: */
0619: public ServerSocketFactory getFactory() {
0620:
0621: return (this .factory);
0622:
0623: }
0624:
0625: /**
0626: * Set the server socket factory used by this Container.
0627: *
0628: * @param factory The new server socket factory
0629: */
0630: public void setFactory(ServerSocketFactory factory) {
0631:
0632: this .factory = factory;
0633:
0634: }
0635:
0636: /**
0637: * Return descriptive information about this Connector implementation.
0638: */
0639: public String getInfo() {
0640:
0641: return (info);
0642:
0643: }
0644:
0645: /**
0646: * Return the mapper.
0647: */
0648: public Mapper getMapper() {
0649:
0650: return (mapper);
0651:
0652: }
0653:
0654: /**
0655: * Return the minimum number of processors to start at initialization.
0656: */
0657: public int getMinProcessors() {
0658:
0659: return (minProcessors);
0660:
0661: }
0662:
0663: /**
0664: * Set the minimum number of processors to start at initialization.
0665: *
0666: * @param minProcessors The new minimum processors
0667: */
0668: public void setMinProcessors(int minProcessors) {
0669:
0670: this .minProcessors = minProcessors;
0671: setProperty("minProcessors", String.valueOf(minProcessors));
0672:
0673: }
0674:
0675: /**
0676: * Return the maximum number of processors allowed, or <0 for unlimited.
0677: */
0678: public int getMaxProcessors() {
0679:
0680: return (maxProcessors);
0681:
0682: }
0683:
0684: /**
0685: * Set the maximum number of processors allowed, or <0 for unlimited.
0686: *
0687: * @param maxProcessors The new maximum processors
0688: */
0689: public void setMaxProcessors(int maxProcessors) {
0690:
0691: this .maxProcessors = maxProcessors;
0692: setProperty("maxThreads", String.valueOf(maxProcessors));
0693:
0694: }
0695:
0696: /**
0697: * Return the processor thread priority.
0698: *
0699: * @return int
0700: */
0701: public int getThreadPriority() {
0702: return threadPriority;
0703: }
0704:
0705: /**
0706: * Sets the processor thread priority.
0707: *
0708: * @param threadPriority The new priority level
0709: */
0710: public void setThreadPriority(int threadPriority) {
0711: this .threadPriority = threadPriority;
0712: setProperty("threadPriority", String.valueOf(threadPriority));
0713: }
0714:
0715: /**
0716: * Return the maximum size of a POST which will be automatically
0717: * parsed by the container.
0718: */
0719: public int getMaxPostSize() {
0720:
0721: return (maxPostSize);
0722:
0723: }
0724:
0725: /**
0726: * Set the maximum size of a POST which will be automatically
0727: * parsed by the container.
0728: *
0729: * @param maxPostSize The new maximum size in bytes of a POST which will
0730: * be automatically parsed by the container
0731: */
0732: public void setMaxPostSize(int maxPostSize) {
0733:
0734: this .maxPostSize = maxPostSize;
0735: setProperty("maxPostSize", String.valueOf(maxPostSize));
0736: }
0737:
0738: /**
0739: * Return the port number on which we listen for requests.
0740: */
0741: public int getPort() {
0742:
0743: return (this .port);
0744:
0745: }
0746:
0747: /**
0748: * Set the port number on which we listen for requests.
0749: *
0750: * @param port The new port number
0751: */
0752: public void setPort(int port) {
0753:
0754: this .port = port;
0755: setProperty("port", String.valueOf(port));
0756:
0757: }
0758:
0759: /**
0760: * Return the Coyote protocol handler in use.
0761: */
0762: public String getProtocol() {
0763:
0764: if ("org.apache.coyote.http11.Http11Protocol"
0765: .equals(getProtocolHandlerClassName())) {
0766: return "HTTP/1.1";
0767: } else if ("org.apache.jk.server.JkCoyoteHandler"
0768: .equals(getProtocolHandlerClassName())) {
0769: return "AJP/1.3";
0770: }
0771: return null;
0772:
0773: }
0774:
0775: /**
0776: * Set the Coyote protocol which will be used by the connector.
0777: *
0778: * @param protocol The Coyote protocol name
0779: */
0780: public void setProtocol(String protocol) {
0781:
0782: if (protocol.equals("HTTP/1.1")) {
0783: setProtocolHandlerClassName("org.apache.coyote.http11.Http11Protocol");
0784: } else if (protocol.equals("AJP/1.3")) {
0785: setProtocolHandlerClassName("org.apache.jk.server.JkCoyoteHandler");
0786: } else {
0787: setProtocolHandlerClassName(null);
0788: }
0789:
0790: }
0791:
0792: /**
0793: * Return the class name of the Coyote protocol handler in use.
0794: */
0795: public String getProtocolHandlerClassName() {
0796:
0797: return (this .protocolHandlerClassName);
0798:
0799: }
0800:
0801: /**
0802: * Set the class name of the Coyote protocol handler which will be used
0803: * by the connector.
0804: *
0805: * @param protocolHandlerClassName The new class name
0806: */
0807: public void setProtocolHandlerClassName(
0808: String protocolHandlerClassName) {
0809:
0810: this .protocolHandlerClassName = protocolHandlerClassName;
0811:
0812: }
0813:
0814: /**
0815: * Return the protocol handler associated with the connector.
0816: */
0817: public ProtocolHandler getProtocolHandler() {
0818:
0819: return (this .protocolHandler);
0820:
0821: }
0822:
0823: /**
0824: * Return the proxy server name for this Connector.
0825: */
0826: public String getProxyName() {
0827:
0828: return (this .proxyName);
0829:
0830: }
0831:
0832: /**
0833: * Set the proxy server name for this Connector.
0834: *
0835: * @param proxyName The new proxy server name
0836: */
0837: public void setProxyName(String proxyName) {
0838:
0839: if (proxyName != null && proxyName.length() > 0) {
0840: this .proxyName = proxyName;
0841: setProperty("proxyName", proxyName);
0842: } else {
0843: this .proxyName = null;
0844: removeProperty("proxyName");
0845: }
0846:
0847: }
0848:
0849: /**
0850: * Return the proxy server port for this Connector.
0851: */
0852: public int getProxyPort() {
0853:
0854: return (this .proxyPort);
0855:
0856: }
0857:
0858: /**
0859: * Set the proxy server port for this Connector.
0860: *
0861: * @param proxyPort The new proxy server port
0862: */
0863: public void setProxyPort(int proxyPort) {
0864:
0865: this .proxyPort = proxyPort;
0866: setProperty("proxyPort", String.valueOf(proxyPort));
0867:
0868: }
0869:
0870: /**
0871: * Return the port number to which a request should be redirected if
0872: * it comes in on a non-SSL port and is subject to a security constraint
0873: * with a transport guarantee that requires SSL.
0874: */
0875: public int getRedirectPort() {
0876:
0877: return (this .redirectPort);
0878:
0879: }
0880:
0881: /**
0882: * Set the redirect port number.
0883: *
0884: * @param redirectPort The redirect port number (non-SSL to SSL)
0885: */
0886: public void setRedirectPort(int redirectPort) {
0887:
0888: this .redirectPort = redirectPort;
0889: setProperty("redirectPort", String.valueOf(redirectPort));
0890:
0891: }
0892:
0893: /**
0894: * Return the flag that specifies upload time-out behavior.
0895: */
0896: public boolean getDisableUploadTimeout() {
0897: return disableUploadTimeout;
0898: }
0899:
0900: /**
0901: * Set the flag to specify upload time-out behavior.
0902: *
0903: * @param isDisabled If <code>true</code>, then the <code>timeout</code>
0904: * parameter is ignored. If <code>false</code>, then the
0905: * <code>timeout</code> parameter is used to control uploads.
0906: */
0907: public void setDisableUploadTimeout(boolean isDisabled) {
0908: disableUploadTimeout = isDisabled;
0909: setProperty("disableUploadTimeout", String.valueOf(isDisabled));
0910: }
0911:
0912: /**
0913: * Return the Keep-Alive policy for the connection.
0914: */
0915: public boolean getKeepAlive() {
0916: return ((maxKeepAliveRequests != 0) && (maxKeepAliveRequests != 1));
0917: }
0918:
0919: /**
0920: * Set the keep-alive policy for this connection.
0921: */
0922: public void setKeepAlive(boolean keepAlive) {
0923: if (!keepAlive) {
0924: setMaxKeepAliveRequests(1);
0925: }
0926: }
0927:
0928: /**
0929: * Return the maximum HTTP header size.
0930: */
0931: public int getMaxHttpHeaderSize() {
0932: return maxHttpHeaderSize;
0933: }
0934:
0935: /**
0936: * Set the maximum HTTP header size.
0937: */
0938: public void setMaxHttpHeaderSize(int size) {
0939: maxHttpHeaderSize = size;
0940: setProperty("maxHttpHeaderSize", String.valueOf(size));
0941: }
0942:
0943: /**
0944: * Return the maximum number of Keep-Alive requests to honor
0945: * per connection.
0946: */
0947: public int getMaxKeepAliveRequests() {
0948: return maxKeepAliveRequests;
0949: }
0950:
0951: /**
0952: * Set the maximum number of Keep-Alive requests to honor per connection.
0953: */
0954: public void setMaxKeepAliveRequests(int mkar) {
0955: maxKeepAliveRequests = mkar;
0956: setProperty("maxKeepAliveRequests", String.valueOf(mkar));
0957: }
0958:
0959: /**
0960: * Return the scheme that will be assigned to requests received
0961: * through this connector. Default value is "http".
0962: */
0963: public String getScheme() {
0964:
0965: return (this .scheme);
0966:
0967: }
0968:
0969: /**
0970: * Set the scheme that will be assigned to requests received through
0971: * this connector.
0972: *
0973: * @param scheme The new scheme
0974: */
0975: public void setScheme(String scheme) {
0976:
0977: this .scheme = scheme;
0978: setProperty("scheme", scheme);
0979:
0980: }
0981:
0982: /**
0983: * Return the secure connection flag that will be assigned to requests
0984: * received through this connector. Default value is "false".
0985: */
0986: public boolean getSecure() {
0987:
0988: return (this .secure);
0989:
0990: }
0991:
0992: /**
0993: * Set the secure connection flag that will be assigned to requests
0994: * received through this connector.
0995: *
0996: * @param secure The new secure connection flag
0997: */
0998: public void setSecure(boolean secure) {
0999:
1000: this .secure = secure;
1001: setProperty("secure", String.valueOf(secure));
1002:
1003: }
1004:
1005: public boolean getTomcatAuthentication() {
1006: return tomcatAuthentication;
1007: }
1008:
1009: public void setTomcatAuthentication(boolean tomcatAuthentication) {
1010: this .tomcatAuthentication = tomcatAuthentication;
1011: setProperty("tomcatAuthentication", String
1012: .valueOf(tomcatAuthentication));
1013: }
1014:
1015: /**
1016: * Return the TCP no delay flag value.
1017: */
1018: public boolean getTcpNoDelay() {
1019:
1020: return (this .tcpNoDelay);
1021:
1022: }
1023:
1024: /**
1025: * Set the TCP no delay flag which will be set on the socket after
1026: * accepting a connection.
1027: *
1028: * @param tcpNoDelay The new TCP no delay flag
1029: */
1030: public void setTcpNoDelay(boolean tcpNoDelay) {
1031:
1032: this .tcpNoDelay = tcpNoDelay;
1033: setProperty("tcpNoDelay", String.valueOf(tcpNoDelay));
1034:
1035: }
1036:
1037: /**
1038: * Return the character encoding to be used for the URI.
1039: */
1040: public String getURIEncoding() {
1041:
1042: return (this .URIEncoding);
1043:
1044: }
1045:
1046: /**
1047: * Set the URI encoding to be used for the URI.
1048: *
1049: * @param URIEncoding The new URI character encoding.
1050: */
1051: public void setURIEncoding(String URIEncoding) {
1052:
1053: this .URIEncoding = URIEncoding;
1054: setProperty("uRIEncoding", URIEncoding);
1055:
1056: }
1057:
1058: /**
1059: * Return the true if the entity body encoding should be used for the URI.
1060: */
1061: public boolean getUseBodyEncodingForURI() {
1062:
1063: return (this .useBodyEncodingForURI);
1064:
1065: }
1066:
1067: /**
1068: * Set if the entity body encoding should be used for the URI.
1069: *
1070: * @param useBodyEncodingForURI The new value for the flag.
1071: */
1072: public void setUseBodyEncodingForURI(boolean useBodyEncodingForURI) {
1073:
1074: this .useBodyEncodingForURI = useBodyEncodingForURI;
1075: setProperty("useBodyEncodingForURI", String
1076: .valueOf(useBodyEncodingForURI));
1077:
1078: }
1079:
1080: /**
1081: * Indicates whether the generation of an X-Powered-By response header for
1082: * servlet-generated responses is enabled or disabled for this Connector.
1083: *
1084: * @return true if generation of X-Powered-By response header is enabled,
1085: * false otherwise
1086: */
1087: public boolean isXpoweredBy() {
1088: return xpoweredBy;
1089: }
1090:
1091: /**
1092: * Enables or disables the generation of an X-Powered-By header (with value
1093: * Servlet/2.4) for all servlet-generated responses returned by this
1094: * Connector.
1095: *
1096: * @param xpoweredBy true if generation of X-Powered-By response header is
1097: * to be enabled, false otherwise
1098: */
1099: public void setXpoweredBy(boolean xpoweredBy) {
1100: this .xpoweredBy = xpoweredBy;
1101: setProperty("xpoweredBy", String.valueOf(xpoweredBy));
1102: }
1103:
1104: // --------------------------------------------------------- Public Methods
1105:
1106: /**
1107: * Create (or allocate) and return a Request object suitable for
1108: * specifying the contents of a Request to the responsible Container.
1109: */
1110: public Request createRequest() {
1111:
1112: CoyoteRequest request = new CoyoteRequest();
1113: request.setConnector(this );
1114: return (request);
1115:
1116: }
1117:
1118: /**
1119: * Create (or allocate) and return a Response object suitable for
1120: * receiving the contents of a Response from the responsible Container.
1121: */
1122: public Response createResponse() {
1123:
1124: CoyoteResponse response = new CoyoteResponse();
1125: response.setConnector(this );
1126: return (response);
1127:
1128: }
1129:
1130: // -------------------------------------------------------- Private Methods
1131:
1132: /**
1133: * Log a message on the Logger associated with our Container (if any).
1134: *
1135: * @param message Message to be logged
1136: */
1137: private void log(String message) {
1138:
1139: Logger logger = container.getLogger();
1140: String localName = "CoyoteConnector";
1141: if (logger != null)
1142: logger.log(localName + " " + message);
1143: else
1144: System.out.println(localName + " " + message);
1145:
1146: }
1147:
1148: /**
1149: * Log a message on the Logger associated with our Container (if any).
1150: *
1151: * @param message Message to be logged
1152: * @param throwable Associated exception
1153: */
1154: private void log(String message, Throwable throwable) {
1155:
1156: Logger logger = container.getLogger();
1157: String localName = "CoyoteConnector";
1158: if (logger != null)
1159: logger.log(localName + " " + message, throwable);
1160: else {
1161: System.out.println(localName + " " + message);
1162: throwable.printStackTrace(System.out);
1163: }
1164:
1165: }
1166:
1167: // ------------------------------------------------------ Lifecycle Methods
1168:
1169: /**
1170: * Add a lifecycle event listener to this component.
1171: *
1172: * @param listener The listener to add
1173: */
1174: public void addLifecycleListener(LifecycleListener listener) {
1175:
1176: lifecycle.addLifecycleListener(listener);
1177:
1178: }
1179:
1180: /**
1181: * Get the lifecycle listeners associated with this lifecycle. If this
1182: * Lifecycle has no listeners registered, a zero-length array is returned.
1183: */
1184: public LifecycleListener[] findLifecycleListeners() {
1185:
1186: return null;//lifecycle.findLifecycleListeners();
1187:
1188: }
1189:
1190: /**
1191: * Remove a lifecycle event listener from this component.
1192: *
1193: * @param listener The listener to add
1194: */
1195: public void removeLifecycleListener(LifecycleListener listener) {
1196:
1197: lifecycle.removeLifecycleListener(listener);
1198:
1199: }
1200:
1201: /**
1202: * Initialize this connector (create ServerSocket here!)
1203: */
1204: public void initialize() throws LifecycleException {
1205: if (initialized) {
1206: log
1207: .info(sm
1208: .getString("coyoteConnector.alreadyInitialized"));
1209: return;
1210: }
1211:
1212: this .initialized = true;
1213:
1214: if (oname == null && (container instanceof StandardEngine)) {
1215: try {
1216: // we are loaded directly, via API - and no name was given to us
1217: StandardEngine cb = (StandardEngine) container;
1218: String encodedAddr = null;
1219: if (getAddress() != null) {
1220: encodedAddr = URLEncoder.encode(getAddress());
1221: }
1222: String addSuffix = (getAddress() == null) ? ""
1223: : ",address=" + encodedAddr;
1224: oname = new ObjectName(cb.getName()
1225: + ":type=Connector,port=" + getPort()
1226: + addSuffix);
1227: Registry.getRegistry(null, null).registerComponent(
1228: this , oname, null);
1229: controller = oname;
1230: } catch (Exception e) {
1231: log.error("Error registering connector ", e);
1232: }
1233: log.debug("Creating name for connector " + oname);
1234: }
1235:
1236: // Initializa adapter
1237: adapter = new CoyoteAdapter(this );
1238:
1239: // Instantiate protocol handler
1240: try {
1241: Class clazz = Class.forName(protocolHandlerClassName);
1242: protocolHandler = (ProtocolHandler) clazz.newInstance();
1243: } catch (Exception e) {
1244: throw new LifecycleException(
1245: sm
1246: .getString(
1247: "coyoteConnector.protocolHandlerInstantiationFailed",
1248: e));
1249: }
1250: protocolHandler.setAdapter(adapter);
1251:
1252: IntrospectionUtils.setProperty(protocolHandler, "jkHome",
1253: System.getProperty("catalina.base"));
1254:
1255: // Configure secure socket factory
1256: // XXX For backwards compatibility only.
1257: if (factory instanceof CoyoteServerSocketFactory) {
1258: IntrospectionUtils.setProperty(protocolHandler, "secure",
1259: "" + true);
1260: CoyoteServerSocketFactory ssf = (CoyoteServerSocketFactory) factory;
1261: IntrospectionUtils.setProperty(protocolHandler,
1262: "algorithm", ssf.getAlgorithm());
1263: IntrospectionUtils.setProperty(protocolHandler,
1264: "clientauth", ssf.getClientAuth());
1265: IntrospectionUtils.setProperty(protocolHandler, "keystore",
1266: ssf.getKeystoreFile());
1267: IntrospectionUtils.setProperty(protocolHandler,
1268: "randomfile", ssf.getRandomFile());
1269: IntrospectionUtils.setProperty(protocolHandler, "rootfile",
1270: ssf.getRootFile());
1271:
1272: IntrospectionUtils.setProperty(protocolHandler, "keypass",
1273: ssf.getKeystorePass());
1274: IntrospectionUtils.setProperty(protocolHandler, "keytype",
1275: ssf.getKeystoreType());
1276: IntrospectionUtils.setProperty(protocolHandler, "protocol",
1277: ssf.getProtocol());
1278: IntrospectionUtils.setProperty(protocolHandler,
1279: "protocols", ssf.getProtocols());
1280: IntrospectionUtils.setProperty(protocolHandler,
1281: "sSLImplementation", ssf.getSSLImplementation());
1282: IntrospectionUtils.setProperty(protocolHandler, "ciphers",
1283: ssf.getCiphers());
1284: IntrospectionUtils.setProperty(protocolHandler, "keyAlias",
1285: ssf.getKeyAlias());
1286: } else {
1287: IntrospectionUtils.setProperty(protocolHandler, "secure",
1288: "" + secure);
1289: }
1290:
1291: /* Set the configured properties. This only sets the ones that were
1292: * explicitly configured. Default values are the responsibility of
1293: * the protocolHandler.
1294: */
1295: Iterator keys = properties.keySet().iterator();
1296: while (keys.hasNext()) {
1297: String name = (String) keys.next();
1298: String value = properties.get(name).toString();
1299: String trnName = translateAttributeName(name);
1300: IntrospectionUtils.setProperty(protocolHandler, trnName,
1301: value);
1302: }
1303:
1304: try {
1305: protocolHandler.init();
1306: } catch (Exception e) {
1307: throw new LifecycleException(
1308: sm
1309: .getString(
1310: "coyoteConnector.protocolHandlerInitializationFailed",
1311: e));
1312: }
1313: }
1314:
1315: /**
1316: * Pause the connector.
1317: */
1318: public void pause() throws LifecycleException {
1319: try {
1320: protocolHandler.pause();
1321: } catch (Exception e) {
1322: log
1323: .error(
1324: sm
1325: .getString("coyoteConnector.protocolHandlerPauseFailed"),
1326: e);
1327: }
1328: }
1329:
1330: /**
1331: * Pause the connector.
1332: */
1333: public void resume() throws LifecycleException {
1334: try {
1335: protocolHandler.resume();
1336: } catch (Exception e) {
1337: log
1338: .error(
1339: sm
1340: .getString("coyoteConnector.protocolHandlerResumeFailed"),
1341: e);
1342: }
1343: }
1344:
1345: /*
1346: * Translate the attribute name from the legacy Factory names to their
1347: * internal protocol names.
1348: */
1349: private String translateAttributeName(String name) {
1350: if ("clientAuth".equals(name)) {
1351: return "clientauth";
1352: } else if ("keystoreFile".equals(name)) {
1353: return "keystore";
1354: } else if ("randomFile".equals(name)) {
1355: return "randomfile";
1356: } else if ("rootFile".equals(name)) {
1357: return "rootfile";
1358: } else if ("keystorePass".equals(name)) {
1359: return "keypass";
1360: } else if ("keystoreType".equals(name)) {
1361: return "keytype";
1362: } else if ("sslProtocol".equals(name)) {
1363: return "protocol";
1364: } else if ("sslProtocols".equals(name)) {
1365: return "protocols";
1366: }
1367: return name;
1368: }
1369:
1370: /**
1371: * Begin processing requests via this Connector.
1372: *
1373: * @exception LifecycleException if a fatal startup error occurs
1374: */
1375: public void start() throws LifecycleException {
1376: if (!initialized)
1377: initialize();
1378:
1379: // Validate and update our current state
1380: if (started) {
1381: log.info(sm.getString("coyoteConnector.alreadyStarted"));
1382: return;
1383: }
1384: lifecycle.fireLifecycleEvent(START_EVENT, null);
1385: started = true;
1386:
1387: // We can't register earlier - the JMX registration of this happens
1388: // in Server.start callback
1389: if (this .oname != null) {
1390: // We are registred - register the adapter as well.
1391: try {
1392: Registry.getRegistry(null, null).registerComponent(
1393: protocolHandler,
1394: this .domain
1395: + ":type=protocolHandler,className="
1396: + protocolHandlerClassName, null);
1397: } catch (Exception ex) {
1398: log
1399: .error(
1400: sm
1401: .getString("coyoteConnector.protocolRegistrationFailed"),
1402: ex);
1403: }
1404: } else {
1405: log
1406: .info(sm
1407: .getString("coyoteConnector.cannotRegisterProtocol"));
1408: }
1409:
1410: try {
1411: protocolHandler.start();
1412: } catch (Exception e) {
1413: throw new LifecycleException(sm.getString(
1414: "coyoteConnector.protocolHandlerStartFailed", e));
1415: }
1416:
1417: if (this .domain != null) {
1418: mapperListener.setDomain(domain);
1419: //mapperListener.setEngine( service.getContainer().getName() );
1420: mapperListener.init();
1421: try {
1422: Registry.getRegistry(null, null).registerComponent(
1423: mapper, this .domain + ":type=Mapper", "Mapper");
1424: } catch (Exception ex) {
1425: log
1426: .error(
1427: sm
1428: .getString("coyoteConnector.protocolRegistrationFailed"),
1429: ex);
1430: }
1431: }
1432: }
1433:
1434: /**
1435: * Terminate processing requests via this Connector.
1436: *
1437: * @exception LifecycleException if a fatal shutdown error occurs
1438: */
1439: public void stop() throws LifecycleException {
1440:
1441: // Validate and update our current state
1442: if (!started) {
1443: log.error(sm.getString("coyoteConnector.notStarted"));
1444: return;
1445:
1446: }
1447: lifecycle.fireLifecycleEvent(STOP_EVENT, null);
1448: started = false;
1449:
1450: try {
1451: Registry.getRegistry(null, null).unregisterComponent(
1452: new ObjectName(domain, "type", "Mapper"));
1453: Registry.getRegistry(null, null).unregisterComponent(
1454: new ObjectName(domain
1455: + ":type=protocolHandler,className="
1456: + protocolHandlerClassName));
1457: } catch (MalformedObjectNameException e) {
1458: log.info("Error unregistering mapper ", e);
1459: }
1460: try {
1461: protocolHandler.destroy();
1462: } catch (Exception e) {
1463: throw new LifecycleException(sm.getString(
1464: "coyoteConnector.protocolHandlerDestroyFailed", e));
1465: }
1466:
1467: }
1468:
1469: // -------------------- Management methods --------------------
1470:
1471: public String getClientAuth() {
1472: String ret = "false";
1473:
1474: String prop = (String) getProperty("clientauth");
1475: if (prop != null) {
1476: ret = prop;
1477: } else {
1478: ServerSocketFactory factory = this .getFactory();
1479: if (factory instanceof CoyoteServerSocketFactory) {
1480: ret = ((CoyoteServerSocketFactory) factory)
1481: .getClientAuth();
1482: }
1483: }
1484:
1485: return ret;
1486: }
1487:
1488: public void setClientAuth(String clientAuth) {
1489: setProperty("clientauth", clientAuth);
1490: ServerSocketFactory factory = this .getFactory();
1491: if (factory instanceof CoyoteServerSocketFactory) {
1492: ((CoyoteServerSocketFactory) factory)
1493: .setClientAuth(clientAuth);
1494: }
1495: }
1496:
1497: public String getKeystoreFile() {
1498: String ret = (String) getProperty("keystore");
1499: if (ret == null) {
1500: ServerSocketFactory factory = this .getFactory();
1501: if (factory instanceof CoyoteServerSocketFactory) {
1502: ret = ((CoyoteServerSocketFactory) factory)
1503: .getKeystoreFile();
1504: }
1505: }
1506:
1507: return ret;
1508: }
1509:
1510: public void setKeystoreFile(String keystoreFile) {
1511: setProperty("keystore", keystoreFile);
1512: ServerSocketFactory factory = this .getFactory();
1513: if (factory instanceof CoyoteServerSocketFactory) {
1514: ((CoyoteServerSocketFactory) factory)
1515: .setKeystoreFile(keystoreFile);
1516: }
1517: }
1518:
1519: /**
1520: * Return keystorePass
1521: */
1522: public String getKeystorePass() {
1523: String ret = (String) getProperty("keypass");
1524: if (ret == null) {
1525: ServerSocketFactory factory = getFactory();
1526: if (factory instanceof CoyoteServerSocketFactory) {
1527: return ((CoyoteServerSocketFactory) factory)
1528: .getKeystorePass();
1529: }
1530: }
1531:
1532: return ret;
1533: }
1534:
1535: /**
1536: * Set keystorePass
1537: */
1538: public void setKeystorePass(String keystorePass) {
1539: setProperty("keypass", keystorePass);
1540: ServerSocketFactory factory = getFactory();
1541: if (factory instanceof CoyoteServerSocketFactory) {
1542: ((CoyoteServerSocketFactory) factory)
1543: .setKeystorePass(keystorePass);
1544: }
1545: }
1546:
1547: /**
1548: * Gets the list of SSL cipher suites that are to be enabled
1549: *
1550: * @return Comma-separated list of SSL cipher suites, or null if all
1551: * cipher suites supported by the underlying SSL implementation are being
1552: * enabled
1553: */
1554: public String getCiphers() {
1555: String ret = (String) getProperty("ciphers");
1556: if (ret == null) {
1557: ServerSocketFactory factory = getFactory();
1558: if (factory instanceof CoyoteServerSocketFactory) {
1559: ret = ((CoyoteServerSocketFactory) factory)
1560: .getCiphers();
1561: }
1562: }
1563:
1564: return ret;
1565: }
1566:
1567: /**
1568: * Sets the SSL cipher suites that are to be enabled.
1569: *
1570: * Only those SSL cipher suites that are actually supported by
1571: * the underlying SSL implementation will be enabled.
1572: *
1573: * @param ciphers Comma-separated list of SSL cipher suites
1574: */
1575: public void setCiphers(String ciphers) {
1576: setProperty("ciphers", ciphers);
1577: ServerSocketFactory factory = getFactory();
1578: if (factory instanceof CoyoteServerSocketFactory) {
1579: ((CoyoteServerSocketFactory) factory).setCiphers(ciphers);
1580: }
1581: }
1582:
1583: /**
1584: * Gets the alias name of the keypair and supporting certificate chain
1585: * used by this Connector to authenticate itself to SSL clients.
1586: *
1587: * @return The alias name of the keypair and supporting certificate chain
1588: */
1589: public String getKeyAlias() {
1590: String ret = (String) getProperty("keyAlias");
1591: if (ret == null) {
1592: ServerSocketFactory factory = getFactory();
1593: if (factory instanceof CoyoteServerSocketFactory) {
1594: ret = ((CoyoteServerSocketFactory) factory)
1595: .getKeyAlias();
1596: }
1597: }
1598:
1599: return ret;
1600: }
1601:
1602: /**
1603: * Sets the alias name of the keypair and supporting certificate chain
1604: * used by this Connector to authenticate itself to SSL clients.
1605: *
1606: * @param alias The alias name of the keypair and supporting certificate
1607: * chain
1608: */
1609: public void setKeyAlias(String alias) {
1610: setProperty("keyAlias", alias);
1611: ServerSocketFactory factory = getFactory();
1612: if (factory instanceof CoyoteServerSocketFactory) {
1613: ((CoyoteServerSocketFactory) factory).setKeyAlias(alias);
1614: }
1615: }
1616:
1617: /**
1618: * Gets the SSL protocol variant to be used.
1619: *
1620: * @return SSL protocol variant
1621: */
1622: public String getSslProtocol() {
1623: String ret = (String) getProperty("sslProtocol");
1624: if (ret == null) {
1625: ServerSocketFactory factory = getFactory();
1626: if (factory instanceof CoyoteServerSocketFactory) {
1627: ret = ((CoyoteServerSocketFactory) factory)
1628: .getProtocol();
1629: }
1630: }
1631:
1632: return ret;
1633: }
1634:
1635: /**
1636: * Sets the SSL protocol variant to be used.
1637: *
1638: * @param sslProtocol SSL protocol variant
1639: */
1640: public void setSslProtocol(String sslProtocol) {
1641: setProperty("sslProtocol", sslProtocol);
1642: ServerSocketFactory factory = getFactory();
1643: if (factory instanceof CoyoteServerSocketFactory) {
1644: ((CoyoteServerSocketFactory) factory)
1645: .setProtocol(sslProtocol);
1646: }
1647: }
1648:
1649: /**
1650: * Gets the SSL protocol variants to be enabled.
1651: *
1652: * @return Comma-separated list of SSL protocol variants
1653: */
1654: public String getSslProtocols() {
1655: String ret = (String) getProperty("sslProtocols");
1656: if (ret == null) {
1657: ServerSocketFactory factory = getFactory();
1658: if (factory instanceof CoyoteServerSocketFactory) {
1659: ret = ((CoyoteServerSocketFactory) factory)
1660: .getProtocols();
1661: }
1662: }
1663:
1664: return ret;
1665: }
1666:
1667: /**
1668: * Sets the SSL protocol variants to be enabled.
1669: *
1670: * @param sslProtocols Comma-separated list of SSL protocol variants
1671: */
1672: public void setSslProtocols(String sslProtocols) {
1673: setProperty("sslProtocols", sslProtocols);
1674: ServerSocketFactory factory = getFactory();
1675: if (factory instanceof CoyoteServerSocketFactory) {
1676: ((CoyoteServerSocketFactory) factory)
1677: .setProtocols(sslProtocols);
1678: }
1679: }
1680:
1681: // -------------------- JMX registration --------------------
1682: protected String domain;
1683: protected ObjectName oname;
1684: protected MBeanServer mserver;
1685: ObjectName controller;
1686:
1687: public ObjectName getController() {
1688: return controller;
1689: }
1690:
1691: public void setController(ObjectName controller) {
1692: this .controller = controller;
1693: }
1694:
1695: public ObjectName getObjectName() {
1696: return oname;
1697: }
1698:
1699: public String getDomain() {
1700: return domain;
1701: }
1702:
1703: public ObjectName preRegister(MBeanServer server, ObjectName name)
1704: throws Exception {
1705: oname = name;
1706: mserver = server;
1707: domain = name.getDomain();
1708: return name;
1709: }
1710:
1711: public void postRegister(Boolean registrationDone) {
1712: }
1713:
1714: public void preDeregister() throws Exception {
1715: }
1716:
1717: public void postDeregister() {
1718: try {
1719: if (started) {
1720: stop();
1721: }
1722: } catch (Throwable t) {
1723: log.error("Unregistering - can't stop", t);
1724: }
1725: }
1726:
1727: private void findContainer() {
1728: try {
1729: // Register to the service
1730: ObjectName parentName = new ObjectName(domain + ":"
1731: + "type=Service");
1732:
1733: log.debug("Adding to " + parentName);
1734: if (mserver.isRegistered(parentName)) {
1735: mserver
1736: .invoke(
1737: parentName,
1738: "addConnector",
1739: new Object[] { this },
1740: new String[] { "org.apache.catalina.Connector" });
1741: // As a side effect we'll get the container field set
1742: // Also initialize will be called
1743: //return;
1744: }
1745: // XXX Go directly to the Engine
1746: // initialize(); - is called by addConnector
1747: ObjectName engName = new ObjectName(domain + ":"
1748: + "type=Engine");
1749: if (mserver.isRegistered(engName)) {
1750: Object obj = mserver.getAttribute(engName,
1751: "managedResource");
1752: log.debug("Found engine " + obj + " " + obj.getClass());
1753: container = (Container) obj;
1754:
1755: // Internal initialize - we now have the Engine
1756: initialize();
1757:
1758: log.debug("Initialized");
1759: // As a side effect we'll get the container field set
1760: // Also initialize will be called
1761: return;
1762: }
1763: } catch (Exception ex) {
1764: log.error("Error finding container " + ex);
1765: }
1766: }
1767:
1768: public void init() throws Exception {
1769:
1770: if (this .getService() != null) {
1771: log.debug("Already configured");
1772: return;
1773: }
1774: if (container == null) {
1775: findContainer();
1776: }
1777: }
1778:
1779: public void destroy() throws Exception {
1780: if (oname != null && controller == oname) {
1781: log.debug("Unregister itself " + oname);
1782: Registry.getRegistry(null, null).unregisterComponent(oname);
1783: }
1784: if (getService() == null)
1785: return;
1786: getService().removeConnector(this);
1787: }
1788:
1789: }
|