tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From r...@apache.org
Subject cvs commit: jakarta-tomcat-connectors/coyote/src/java/org/apache/coyote/tomcat4 CoyoteAdapter.java CoyoteConnector2.java
Date Sat, 06 Apr 2002 12:24:05 GMT
remm        02/04/06 04:24:05

  Added:       coyote/src/java/org/apache/coyote/tomcat4 CoyoteAdapter.java
                        CoyoteConnector2.java
  Log:
  - Add draft of the connector based on the protocol handler.
  
  Revision  Changes    Path
  1.1                  jakarta-tomcat-connectors/coyote/src/java/org/apache/coyote/tomcat4/CoyoteAdapter.java
  
  Index: CoyoteAdapter.java
  ===================================================================
  /* * $Header: /home/cvs/jakarta-tomcat-connectors/coyote/src/java/org/apache/coyote/tomcat4/CoyoteAdapter.java,v
1.1 2002/04/06 12:24:05 remm Exp $
   * $Revision: 1.1 $
   * $Date: 2002/04/06 12:24:05 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * [Additional notices, if required by prior licensing conditions]
   *
   */
  
  
  package org.apache.coyote.tomcat4;
  
  
  import java.io.BufferedInputStream;
  import java.io.EOFException;
  import java.io.InterruptedIOException;
  import java.io.InputStream;
  import java.io.IOException;
  import java.io.OutputStream;
  import java.net.InetAddress;
  import java.net.Socket;
  import java.util.ArrayList;
  import java.util.Enumeration;
  import java.util.Iterator;
  import java.util.Locale;
  import java.util.StringTokenizer;
  import java.util.TreeMap;
  import javax.servlet.ServletException;
  import javax.servlet.http.Cookie;
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;
  
  import org.apache.tomcat.util.buf.ByteChunk;
  import org.apache.tomcat.util.buf.HexUtils;
  import org.apache.tomcat.util.buf.MessageBytes;
  import org.apache.tomcat.util.http.Cookies;
  import org.apache.tomcat.util.http.ServerCookie;
  
  import org.apache.coyote.ActionCode;
  import org.apache.coyote.ActionHook;
  import org.apache.coyote.Adapter;
  import org.apache.coyote.InputBuffer;
  import org.apache.coyote.OutputBuffer;
  import org.apache.coyote.Request;
  import org.apache.coyote.Response;
  
  import org.apache.catalina.Connector;
  import org.apache.catalina.Container;
  import org.apache.catalina.Globals;
  import org.apache.catalina.HttpRequest;
  import org.apache.catalina.HttpResponse;
  import org.apache.catalina.Lifecycle;
  import org.apache.catalina.LifecycleEvent;
  import org.apache.catalina.LifecycleException;
  import org.apache.catalina.LifecycleListener;
  import org.apache.catalina.Logger;
  import org.apache.catalina.util.LifecycleSupport;
  import org.apache.catalina.util.RequestUtil;
  import org.apache.catalina.util.StringManager;
  import org.apache.catalina.util.StringParser;
  
  
  /**
   * Implementation of a request processor which delegates the processing to a
   * Coyote processor.
   *
   * @author Craig R. McClanahan
   * @author Remy Maucherat
   * @version $Revision: 1.1 $ $Date: 2002/04/06 12:24:05 $
   */
  
  final class CoyoteAdapter
      implements Adapter {
  
  
      // -------------------------------------------------------------- Constants
  
  
      public static final int ADAPTER_NOTES = 0;
  
  
      // ----------------------------------------------------------- Constructors
  
  
      /**
       * Construct a new CoyoteProcessor associated with the specified connector.
       *
       * @param connector CoyoteConnector that owns this processor
       * @param id Identifier of this CoyoteProcessor (unique per connector)
       */
      public CoyoteAdapter(CoyoteConnector2 connector) {
  
          super();
          this.connector = connector;
          this.debug = connector.getDebug();
  
      }
  
  
      // ----------------------------------------------------- Instance Variables
  
  
      /**
       * The CoyoteConnector with which this processor is associated.
       */
      private CoyoteConnector2 connector = null;
  
  
      /**
       * The debugging detail level for this component.
       */
      private int debug = 0;
  
  
      /**
       * The match string for identifying a session ID parameter.
       */
      private static final String match =
          ";" + Globals.SESSION_PARAMETER_NAME + "=";
  
  
      /**
       * The match string for identifying a session ID parameter.
       */
      private static final char[] SESSION_ID = match.toCharArray();
  
  
      /**
       * The string manager for this package.
       */
      protected StringManager sm =
          StringManager.getManager(Constants.Package);
  
  
      // -------------------------------------------------------- Adapter Methods
  
  
      /**
       * Service method.
       */
      public void service(Request req, Response res)
          throws Exception {
  
          CoyoteRequest request = (CoyoteRequest) req.getNote(ADAPTER_NOTES);
          CoyoteResponse response = (CoyoteResponse) res.getNote(ADAPTER_NOTES);
  
          if (request == null) {
  
              // Create objects
              request = (CoyoteRequest) connector.createRequest();
              request.setCoyoteRequest(req);
              response = (CoyoteResponse) connector.createResponse();
              response.setCoyoteResponse(res);
  
              // Link objects
              request.setResponse(response);
              response.setRequest(request);
  
              // Set as notes
              req.setNote(ADAPTER_NOTES, request);
              res.setNote(ADAPTER_NOTES, response);
  
          }
  
          try {
              // Parse and set Catalina and configuration specific 
              // request parameters
              postParseRequest(req, request, res, response);
              // Calling the container
              connector.getContainer().invoke(request, response);
              response.finishResponse();
          } catch (IOException e) {
              ;
          } catch (Throwable t) {
              log(sm.getString("coyoteProcessor.service"), t);
          } finally {
              // Recycle the wrapper request and response
              request.recycle();
              response.recycle();
          }
  
      }
  
  
      // ------------------------------------------------------ Protected Methods
  
  
      /**
       * Parse additional request parameters.
       */
      protected void postParseRequest(Request req, CoyoteRequest request,
                                      Response res, CoyoteResponse response)
          throws IOException {
  
          request.setSecure(connector.getSecure());
          req.scheme().setString(connector.getScheme());
  
          request.setAuthorization
              (req.getHeader(Constants.AUTHORIZATION_HEADER));
  
          // At this point the Host header has been processed.
          // Override if the proxyPort/proxyHost are set 
  
          // Replace the default port if we are in secure mode
          if (req.getServerPort() == 80 
              && connector.getScheme().equals("https")) {
              req.setServerPort(443);
          }
  
          String proxyName = connector.getProxyName();
          int proxyPort = connector.getProxyPort();
          
          if (proxyPort != 0) {
              request.setServerPort(proxyPort);
              req.setServerPort( proxyPort );
          } else {
              request.setServerPort(req.getServerPort());
          }
  
          if (proxyName != null) {
              request.setServerName(proxyName);
              req.serverName().setString(proxyName);
          } else {
              request.setServerName(req.serverName().toString());
          }
  
          if (!normalize(req.decodedURI())) {
              res.setStatus(400);
              res.setMessage("Invalid URI");
              throw new IOException("Invalid URI");
          }
  
          parseSessionId(req, request);
  
          // Additional URI normalization and validation is needed for security 
          // reasons on Tomcat 4.0.x
          if (connector.getUseURIValidationHack()) {
              String uri = validate(request.getRequestURI());
              if (uri == null) {
                  res.setStatus(400);
                  res.setMessage("Invalid URI");
                  throw new IOException("Invalid URI");
              } else {
                  req.requestURI().setString(uri);
                  // Redoing the URI decoding
                  req.decodedURI().duplicate(req.requestURI());
                  req.getURLDecoder().convert(req.decodedURI(), true);
              }
          }
  
          parseCookies(req, request);
  
      }
  
      /**
       * Parse session id in URL.
       * FIXME: Optimize this.
       */
      protected void parseSessionId(Request req, CoyoteRequest request) {
  
          ByteChunk uriBC = req.decodedURI().getByteChunk();
          int semicolon = uriBC.indexOf(match, 0, match.length(), 0);
  
          if (semicolon > 0) {
  
              // Parse session ID, and extract it from the decoded request URI
              String uri = uriBC.toString();
              String rest = uri.substring(semicolon + match.length());
              int semicolon2 = rest.indexOf(';');
              if (semicolon2 >= 0) {
                  request.setRequestedSessionId(rest.substring(0, semicolon2));
                  rest = rest.substring(semicolon2);
              } else {
                  request.setRequestedSessionId(rest);
                  rest = "";
              }
              request.setRequestedSessionURL(true);
              req.decodedURI().setString(uri.substring(0, semicolon) + rest);
  
              // Extract session ID from request URI
              uri = req.requestURI().toString();
              semicolon = uri.indexOf(match);
  
              if (semicolon > 0) {
                  rest = uri.substring(semicolon + match.length());
                  semicolon2 = rest.indexOf(';');
                  if (semicolon2 >= 0) {
                      rest = rest.substring(semicolon2);
                  } else {
                      rest = "";
                  }
                  req.requestURI().setString(uri.substring(0, semicolon) + rest);
              }
  
          } else {
              request.setRequestedSessionId(null);
              request.setRequestedSessionURL(false);
          }
  
      }
  
  
      /**
       * Parse cookies.
       */
      protected void parseCookies(Request req, CoyoteRequest request) {
  
          Cookies serverCookies = req.getCookies();
          int count = serverCookies.getCookieCount();
          if (count <= 0)
              return;
  
          Cookie[] cookies = new Cookie[count];
  
          for (int i = 0; i < count; i++) {
              ServerCookie scookie = serverCookies.getCookie(i);
              if (scookie.getName().equals(Globals.SESSION_COOKIE_NAME)) {
                  // Override anything requested in the URL
                  if (!request.isRequestedSessionIdFromCookie()) {
                      // Accept only the first session id cookie
                      request.setRequestedSessionId
                          (scookie.getValue().toString());
                      request.setRequestedSessionCookie(true);
                      request.setRequestedSessionURL(false);
                      if (debug >= 1)
                          log(" Requested cookie session id is " +
                              ((HttpServletRequest) request.getRequest())
                              .getRequestedSessionId());
                  }
              }
              Cookie cookie = new Cookie(scookie.getName().toString(),
                                         scookie.getValue().toString());
              cookies[i] = cookie;
          }
  
          request.setCookies(cookies);
  
      }
  
  
      /**
       * Return a context-relative path, beginning with a "/", that represents
       * the canonical version of the specified path after ".." and "." elements
       * are resolved out.  If the specified path attempts to go outside the
       * boundaries of the current context (i.e. too many ".." path elements
       * are present), return <code>null</code> instead.
       *
       * @param path Path to be validated
       */
      protected static String validate(String path) {
  
          if (path == null)
              return null;
  
          // Create a place for the normalized path
          String normalized = path;
  
          // Normalize "/%7E" and "/%7e" at the beginning to "/~"
          if (normalized.startsWith("/%7E") ||
              normalized.startsWith("/%7e"))
              normalized = "/~" + normalized.substring(4);
  
          // Prevent encoding '%', '/', '.' and '\', which are special reserved
          // characters
          if ((normalized.indexOf("%25") >= 0)
              || (normalized.indexOf("%2F") >= 0)
              || (normalized.indexOf("%2E") >= 0)
              || (normalized.indexOf("%5C") >= 0)
              || (normalized.indexOf("%2f") >= 0)
              || (normalized.indexOf("%2e") >= 0)
              || (normalized.indexOf("%5c") >= 0)) {
              return null;
          }
  
          if (normalized.equals("/."))
              return "/";
  
          // Normalize the slashes and add leading slash if necessary
          if (normalized.indexOf('\\') >= 0)
              normalized = normalized.replace('\\', '/');
          if (!normalized.startsWith("/"))
              normalized = "/" + normalized;
  
          // Resolve occurrences of "//" in the normalized path
          while (true) {
              int index = normalized.indexOf("//");
              if (index < 0)
                  break;
              normalized = normalized.substring(0, index) +
                  normalized.substring(index + 1);
          }
  
          // Resolve occurrences of "/./" in the normalized path
          while (true) {
              int index = normalized.indexOf("/./");
              if (index < 0)
                  break;
              normalized = normalized.substring(0, index) +
                  normalized.substring(index + 2);
          }
  
          // Resolve occurrences of "/../" in the normalized path
          while (true) {
              int index = normalized.indexOf("/../");
              if (index < 0)
                  break;
              if (index == 0)
                  return (null);  // Trying to go outside our context
              int index2 = normalized.lastIndexOf('/', index - 1);
              normalized = normalized.substring(0, index2) +
                  normalized.substring(index + 3);
          }
  
          // Declare occurrences of "/..." (three or more dots) to be invalid
          // (on some Windows platforms this walks the directory tree!!!)
          if (normalized.indexOf("/...") >= 0)
              return (null);
  
          // Return the normalized path that we have completed
          return (normalized);
  
      }
  
  
      /**
       * Normalize URI.
       * <p>
       * This method normalizes '/./' and '/../'.
       * 
       * @param uri URI to be normalized
       */
      public static boolean normalize(MessageBytes uriMB) {
  
          ByteChunk uriBC = uriMB.getByteChunk();
          byte[] b = uriBC.getBytes();
          int start = uriBC.getStart();
          int end = uriBC.getEnd();
  
          int pos = 0;
          int index = 0;
  
          // Replace '\' with '/'
          for (pos = start; pos < end; pos++) {
              if (b[pos] == (byte) '\\')
                  b[pos] = (byte) '/';
          }
  
          // Replace "//" with "/"
          for (pos = start; pos < (end - 1); pos++) {
              if ((b[pos] == (byte) '/') && (b[pos + 1] == (byte) '/')) {
                  copyBytes(b, pos, pos + 1, end - pos - 1);
                  end--;
              }
          }
  
          // If the URI ends with "/." or "/..", then we append an extra "/"
          // Note: It is possible to extend the URI by 1 without any side effect
          // as the next character in a non-significant WS.
          if (((end - start) > 2) && (b[end - 1] == (byte) '.')) {
              if ((b[end - 2] == (byte) '/') 
                  || ((b[end - 2] == (byte) '.') 
                      && (b[end - 3] == (byte) '/'))) {
                  b[end] = (byte) '/';
                  end++;
              }
          }
  
          uriBC.setEnd(end);
  
          index = 0;
  
          // Resolve occurrences of "/./" in the normalized path
          while (true) {
              index = uriBC.indexOf("/./", 0, 3, index);
              if (index < 0)
                  break;
              copyBytes(b, start + index, start + index + 2, 
                        end - start - index - 2);
              end = end - 2;
              uriBC.setEnd(end);
          }
  
          index = 0;
  
          // Resolve occurrences of "/../" in the normalized path
          while (true) {
              index = uriBC.indexOf("/../", 0, 4, index);
              if (index < 0)
                  break;
              // Prevent from going outside our context
              if (index == 0)
                  return false;
              int index2 = -1;
              for (pos = start + index - 1; (pos >= 0) && (index2 < 0); pos
--) {
                  if (b[pos] == (byte) '/') {
                      index2 = pos;
                  }
              }
              copyBytes(b, start + index2, start + index + 3,
                        end - start - index - 3);
              end = end + index2 - index - 3;
              uriBC.setEnd(end);
              index = index2;
          }
  
          uriBC.setBytes(b, start, end);
  
          return true;
  
      }
  
  
      // ------------------------------------------------------ Protected Methods
  
  
      /**
       * Copy an array of bytes to a different position. Used during 
       * normalization.
       */
      protected static void copyBytes(byte[] b, int dest, int src, int len) {
          for (int pos = 0; pos < len; pos++) {
              b[pos + dest] = b[pos + src];
          }
      }
  
  
      /**
       * Log a message on the Logger associated with our Container (if any)
       *
       * @param message Message to be logged
       */
      protected void log(String message) {
  
          Logger logger = connector.getContainer().getLogger();
          if (logger != null)
              logger.log("CoyoteAdapter " + message);
  
      }
  
  
      /**
       * Log a message on the Logger associated with our Container (if any)
       *
       * @param message Message to be logged
       * @param throwable Associated exception
       */
      protected void log(String message, Throwable throwable) {
  
          Logger logger = connector.getContainer().getLogger();
          if (logger != null)
              logger.log("CoyoteAdapter " + message, throwable);
  
      }
  
  
  }
  
  
  
  1.1                  jakarta-tomcat-connectors/coyote/src/java/org/apache/coyote/tomcat4/CoyoteConnector2.java
  
  Index: CoyoteConnector2.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-tomcat-connectors/coyote/src/java/org/apache/coyote/tomcat4/CoyoteConnector2.java,v
1.1 2002/04/06 12:24:05 remm Exp $
   * $Revision: 1.1 $
   * $Date: 2002/04/06 12:24:05 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * [Additional notices, if required by prior licensing conditions]
   *
   */
  
  
  package org.apache.coyote.tomcat4;
  
  
  import java.io.IOException;
  import java.net.InetAddress;
  import java.net.ServerSocket;
  import java.net.Socket;
  import java.net.UnknownHostException;
  import java.security.AccessControlException;
  import java.util.Stack;
  import java.util.Vector;
  import java.util.Enumeration;
  import java.security.KeyStoreException;
  import java.security.NoSuchAlgorithmException;
  import java.security.cert.CertificateException;
  import java.security.UnrecoverableKeyException;
  import java.security.KeyManagementException;
  
  import org.apache.coyote.ActionCode;
  import org.apache.coyote.ActionHook;
  import org.apache.coyote.Adapter;
  import org.apache.coyote.InputBuffer;
  import org.apache.coyote.OutputBuffer;
  import org.apache.coyote.ProtocolHandler;
  
  import org.apache.catalina.Connector;
  import org.apache.catalina.Container;
  import org.apache.catalina.HttpRequest;
  import org.apache.catalina.HttpResponse;
  import org.apache.catalina.Lifecycle;
  import org.apache.catalina.LifecycleEvent;
  import org.apache.catalina.LifecycleException;
  import org.apache.catalina.LifecycleListener;
  import org.apache.catalina.Logger;
  import org.apache.catalina.Request;
  import org.apache.catalina.Response;
  import org.apache.catalina.Service;
  import org.apache.catalina.net.DefaultServerSocketFactory;
  import org.apache.catalina.net.ServerSocketFactory;
  import org.apache.catalina.util.LifecycleSupport;
  import org.apache.catalina.util.StringManager;
  
  
  /**
   * Implementation of a Coyote connector for Tomcat 4.x.
   *
   * @author Craig R. McClanahan
   * @author Remy Maucherat
   * @version $Revision: 1.1 $ $Date: 2002/04/06 12:24:05 $
   */
  
  
  public final class CoyoteConnector2
      implements Connector, Lifecycle {
  
  
      // ----------------------------------------------------- Instance Variables
  
  
      /**
       * The <code>Service</code> we are associated with (if any).
       */
      private Service service = null;
  
  
      /**
       * The accept count for this Connector.
       */
      private int acceptCount = 10;
  
  
      /**
       * The IP address on which to bind, if any.  If <code>null</code>, all
       * addresses on the server will be bound.
       */
      private String address = null;
  
  
      /**
       * The input buffer size we should create on input streams.
       */
      private int bufferSize = 2048;
  
  
      /**
       * The Container used for processing requests received by this Connector.
       */
      protected Container container = null;
  
  
      /**
       * The set of processors that have ever been created.
       */
      private Vector created = new Vector();
  
  
      /**
       * The current number of processors that have been created.
       */
      private int curProcessors = 0;
  
  
      /**
       * The debugging detail level for this component.
       */
      private int debug = 0;
  
  
      /**
       * The "enable DNS lookups" flag for this Connector.
       */
      private boolean enableLookups = false;
  
  
      /**
       * The server socket factory for this component.
       */
      private ServerSocketFactory factory = null;
  
  
      /**
       * Descriptive information about this Connector implementation.
       */
      private static final String info =
          "org.apache.coyote.tomcat4.CoyoteConnector2/1.0";
  
  
      /**
       * The lifecycle event support for this component.
       */
      protected LifecycleSupport lifecycle = new LifecycleSupport(this);
  
  
      /**
       * The minimum number of processors to start at initialization time.
       */
      protected int minProcessors = 5;
  
  
      /**
       * The maximum number of processors allowed, or <0 for unlimited.
       */
      private int maxProcessors = 20;
  
  
      /**
       * Timeout value on the incoming connection.
       * Note : a value of 0 means no timeout.
       */
      private int connectionTimeout = Constants.DEFAULT_CONNECTION_TIMEOUT;
  
  
      /**
       * The port number on which we listen for requests.
       */
      private int port = 8080;
  
  
      /**
       * The server name to which we should pretend requests to this Connector
       * were directed.  This is useful when operating Tomcat behind a proxy
       * server, so that redirects get constructed accurately.  If not specified,
       * the server name included in the <code>Host</code> header is used.
       */
      private String proxyName = null;
  
  
      /**
       * The server port to which we should pretent requests to this Connector
       * were directed.  This is useful when operating Tomcat behind a proxy
       * server, so that redirects get constructed accurately.  If not specified,
       * the port number specified by the <code>port</code> property is used.
       */
      private int proxyPort = 0;
  
  
      /**
       * The redirect port for non-SSL to SSL redirects.
       */
      private int redirectPort = 443;
  
  
      /**
       * The request scheme that will be set on all requests received
       * through this connector.
       */
      private String scheme = "http";
  
  
      /**
       * The secure connection flag that will be set on all requests received
       * through this connector.
       */
      private boolean secure = false;
  
  
      /**
       * The string manager for this package.
       */
      private StringManager sm =
          StringManager.getManager(Constants.Package);
  
  
      /**
       * Has this component been initialized yet?
       */
      private boolean initialized = false;
  
  
      /**
       * Has this component been started yet?
       */
      private boolean started = false;
  
  
      /**
       * The shutdown signal to our background thread
       */
      private boolean stopped = false;
  
  
      /**
       * The background thread.
       */
      private Thread thread = null;
  
  
      /**
       * Use TCP no delay ?
       */
      private boolean tcpNoDelay = true;
  
  
      /**
       * Coyote Protocol handler class name.
       * Defaults to the Coyote HTTP/1.1 protocolHandler.
       */
      private String protocolHandlerClassName = 
          "org.apache.coyote.http11.Http11Protocol";
  
  
      /**
       * Use URI validation for Tomcat 4.0.x.
       */
      private boolean useURIValidationHack = true;
  
  
      /**
       * Coyote protocol handler.
       */
      private ProtocolHandler protocolHandler = null;
  
  
      /**
       * Coyote adapter.
       */
      private Adapter adapter = null;
  
  
      // ------------------------------------------------------------- Properties
  
  
      /**
       * Return the <code>Service</code> with which we are associated (if any).
       */
      public Service getService() {
  
          return (this.service);
  
      }
  
  
      /**
       * Set the <code>Service</code> with which we are associated (if any).
       *
       * @param service The service that owns this Engine
       */
      public void setService(Service service) {
  
          this.service = service;
  
      }
  
  
      /**
       * Return the connection timeout for this Connector.
       */
      public int getConnectionTimeout() {
  
          return (connectionTimeout);
  
      }
  
  
      /**
       * Set the connection timeout for this Connector.
       *
       * @param count The new connection timeout
       */
      public void setConnectionTimeout(int connectionTimeout) {
  
          this.connectionTimeout = connectionTimeout;
  
      }
  
  
      /**
       * Return the accept count for this Connector.
       */
      public int getAcceptCount() {
  
          return (acceptCount);
  
      }
  
  
      /**
       * Set the accept count for this Connector.
       *
       * @param count The new accept count
       */
      public void setAcceptCount(int count) {
  
          this.acceptCount = count;
  
      }
  
  
      /**
       * Return the bind IP address for this Connector.
       */
      public String getAddress() {
  
          return (this.address);
  
      }
  
  
      /**
       * Set the bind IP address for this Connector.
       *
       * @param address The bind IP address
       */
      public void setAddress(String address) {
  
          this.address = address;
  
      }
  
  
      /**
       * Is this connector available for processing requests?
       */
      public boolean isAvailable() {
  
          return (started);
  
      }
  
  
      /**
       * Return the input buffer size for this Connector.
       */
      public int getBufferSize() {
  
          return (this.bufferSize);
  
      }
  
  
      /**
       * Set the input buffer size for this Connector.
       *
       * @param bufferSize The new input buffer size.
       */
      public void setBufferSize(int bufferSize) {
  
          this.bufferSize = bufferSize;
  
      }
  
  
      /**
       * Return the Container used for processing requests received by this
       * Connector.
       */
      public Container getContainer() {
  
          return (container);
  
      }
  
  
      /**
       * Set the Container used for processing requests received by this
       * Connector.
       *
       * @param container The new Container to use
       */
      public void setContainer(Container container) {
  
          this.container = container;
  
      }
  
  
      /**
       * Return the current number of processors that have been created.
       */
      public int getCurProcessors() {
  
          return (curProcessors);
  
      }
  
  
      /**
       * Return the debugging detail level for this component.
       */
      public int getDebug() {
  
          return (debug);
  
      }
  
  
      /**
       * Set the debugging detail level for this component.
       *
       * @param debug The new debugging detail level
       */
      public void setDebug(int debug) {
  
          this.debug = debug;
  
      }
  
  
      /**
       * Return the "enable DNS lookups" flag.
       */
      public boolean getEnableLookups() {
  
          return (this.enableLookups);
  
      }
  
  
      /**
       * Set the "enable DNS lookups" flag.
       *
       * @param enableLookups The new "enable DNS lookups" flag value
       */
      public void setEnableLookups(boolean enableLookups) {
  
          this.enableLookups = enableLookups;
  
      }
  
  
      /**
       * Return the server socket factory used by this Container.
       */
      public ServerSocketFactory getFactory() {
  
          if (this.factory == null) {
              synchronized (this) {
                  this.factory = new DefaultServerSocketFactory();
              }
          }
          return (this.factory);
  
      }
  
  
      /**
       * Set the server socket factory used by this Container.
       *
       * @param factory The new server socket factory
       */
      public void setFactory(ServerSocketFactory factory) {
  
          this.factory = factory;
  
      }
  
  
      /**
       * Return descriptive information about this Connector implementation.
       */
      public String getInfo() {
  
          return (info);
  
      }
  
  
      /**
       * Return the minimum number of processors to start at initialization.
       */
      public int getMinProcessors() {
  
          return (minProcessors);
  
      }
  
  
      /**
       * Set the minimum number of processors to start at initialization.
       *
       * @param minProcessors The new minimum processors
       */
      public void setMinProcessors(int minProcessors) {
  
          this.minProcessors = minProcessors;
  
      }
  
  
      /**
       * Return the maximum number of processors allowed, or <0 for unlimited.
       */
      public int getMaxProcessors() {
  
          return (maxProcessors);
  
      }
  
  
      /**
       * Set the maximum number of processors allowed, or <0 for unlimited.
       *
       * @param maxProcessors The new maximum processors
       */
      public void setMaxProcessors(int maxProcessors) {
  
          this.maxProcessors = maxProcessors;
  
      }
  
  
      /**
       * Return the port number on which we listen for requests.
       */
      public int getPort() {
  
          return (this.port);
  
      }
  
  
      /**
       * Set the port number on which we listen for requests.
       *
       * @param port The new port number
       */
      public void setPort(int port) {
  
          this.port = port;
  
      }
  
  
      /**
       * Return the class name of the Coyote protocol handler in use.
       */
      public String getProtocolHandlerClassName() {
  
          return (this.protocolHandlerClassName);
  
      }
  
  
      /**
       * Set the class name of the Coyote protocol handler which will be used 
       * by the connector.
       * 
       * @param protocolHandlerClassName The new class name
       */
      public void setProtocolHandlerClassName(String protocolHandlerClassName) {
  
          this.protocolHandlerClassName = protocolHandlerClassName;
  
      }
  
  
      /**
       * Return the proxy server name for this Connector.
       */
      public String getProxyName() {
  
          return (this.proxyName);
  
      }
  
  
      /**
       * Set the proxy server name for this Connector.
       *
       * @param proxyName The new proxy server name
       */
      public void setProxyName(String proxyName) {
  
          this.proxyName = proxyName;
  
      }
  
  
      /**
       * Return the proxy server port for this Connector.
       */
      public int getProxyPort() {
  
          return (this.proxyPort);
  
      }
  
  
      /**
       * Set the proxy server port for this Connector.
       *
       * @param proxyPort The new proxy server port
       */
      public void setProxyPort(int proxyPort) {
  
          this.proxyPort = proxyPort;
  
      }
  
  
      /**
       * Return the port number to which a request should be redirected if
       * it comes in on a non-SSL port and is subject to a security constraint
       * with a transport guarantee that requires SSL.
       */
      public int getRedirectPort() {
  
          return (this.redirectPort);
  
      }
  
  
      /**
       * Set the redirect port number.
       *
       * @param redirectPort The redirect port number (non-SSL to SSL)
       */
      public void setRedirectPort(int redirectPort) {
  
          this.redirectPort = redirectPort;
  
      }
  
  
      /**
       * Return the scheme that will be assigned to requests received
       * through this connector.  Default value is "http".
       */
      public String getScheme() {
  
          return (this.scheme);
  
      }
  
  
      /**
       * Set the scheme that will be assigned to requests received through
       * this connector.
       *
       * @param scheme The new scheme
       */
      public void setScheme(String scheme) {
  
          this.scheme = scheme;
  
      }
  
  
      /**
       * Return the secure connection flag that will be assigned to requests
       * received through this connector.  Default value is "false".
       */
      public boolean getSecure() {
  
          return (this.secure);
  
      }
  
  
      /**
       * Set the secure connection flag that will be assigned to requests
       * received through this connector.
       *
       * @param secure The new secure connection flag
       */
      public void setSecure(boolean secure) {
  
          this.secure = secure;
  
      }
  
  
      /**
       * Return the TCP no delay flag value.
       */
      public boolean getTcpNoDelay() {
  
          return (this.tcpNoDelay);
  
      }
  
  
      /**
       * Set the TCP no delay flag which will be set on the socket after
       * accepting a connection.
       *
       * @param tcpNoDelay The new TCP no delay flag
       */
      public void setTcpNoDelay(boolean tcpNoDelay) {
  
          this.tcpNoDelay = tcpNoDelay;
  
      }
  
  
      /**
       * Return the value of the Uri validation flag.
       */
      public boolean getUseURIValidationHack() {
  
          return (this.useURIValidationHack);
  
      }
  
  
      /**
       * Set the value of the Uri validation flag.
       * 
       * @param useURIValidationHack The new flag value
       */
      public void setUseURIValidationHack(boolean useURIValidationHack) {
  
          this.useURIValidationHack = useURIValidationHack;
  
      }
  
  
      // --------------------------------------------------------- Public Methods
  
  
      /**
       * Create (or allocate) and return a Request object suitable for
       * specifying the contents of a Request to the responsible Container.
       */
      public Request createRequest() {
  
          CoyoteRequest request = new CoyoteRequest();
          request.setConnector(this);
          return (request);
  
      }
  
  
      /**
       * Create (or allocate) and return a Response object suitable for
       * receiving the contents of a Response from the responsible Container.
       */
      public Response createResponse() {
  
          CoyoteResponse response = new CoyoteResponse();
          response.setConnector(this);
          return (response);
  
      }
  
  
      // -------------------------------------------------------- Private Methods
  
  
      /**
       * Log a message on the Logger associated with our Container (if any).
       *
       * @param message Message to be logged
       */
      private void log(String message) {
  
          Logger logger = container.getLogger();
          String localName = "CoyoteConnector";
          if (logger != null)
              logger.log(localName + " " + message);
          else
              System.out.println(localName + " " + message);
  
      }
  
  
      /**
       * Log a message on the Logger associated with our Container (if any).
       *
       * @param message Message to be logged
       * @param throwable Associated exception
       */
      private void log(String message, Throwable throwable) {
  
          Logger logger = container.getLogger();
          String localName = "CoyoteConnector";
          if (logger != null)
              logger.log(localName + " " + message, throwable);
          else {
              System.out.println(localName + " " + message);
              throwable.printStackTrace(System.out);
          }
  
      }
  
  
      // ------------------------------------------------------ Lifecycle Methods
  
  
      /**
       * Add a lifecycle event listener to this component.
       *
       * @param listener The listener to add
       */
      public void addLifecycleListener(LifecycleListener listener) {
  
          lifecycle.addLifecycleListener(listener);
  
      }
  
  
      /**
       * Get the lifecycle listeners associated with this lifecycle. If this 
       * Lifecycle has no listeners registered, a zero-length array is returned.
       */
      public LifecycleListener[] findLifecycleListeners() {
  
          return null;//lifecycle.findLifecycleListeners();
  
      }
  
  
      /**
       * Remove a lifecycle event listener from this component.
       *
       * @param listener The listener to add
       */
      public void removeLifecycleListener(LifecycleListener listener) {
  
          lifecycle.removeLifecycleListener(listener);
  
      }
  
  
      /**
       * Initialize this connector (create ServerSocket here!)
       */
      public void initialize()
          throws LifecycleException {
  
          if (initialized)
              throw new LifecycleException 
                  (sm.getString("coyoteConnector.alreadyInitialized"));
  
          this.initialized = true;
  
          // Initializa adapter
          adapter = new CoyoteAdapter(this);
  
          // Instantiate protocol handler
          try {
              Class clazz = Class.forName(protocolHandlerClassName);
              protocolHandler = (ProtocolHandler) clazz.newInstance();
          } catch (Exception e) {
              throw new LifecycleException
                  (sm.getString
                   ("coyoteProcessor.processorInstantiationFailed", e));
          }
          protocolHandler.setAdapter(adapter);
  
          // Set attributes
          
  
          try {
              protocolHandler.init();
          } catch (Exception e) {
              throw new LifecycleException
                  (sm.getString
                   ("coyoteProcessor.processorInstantiationFailed", e));
          }
  
      }
  
  
      /**
       * Begin processing requests via this Connector.
       *
       * @exception LifecycleException if a fatal startup error occurs
       */
      public void start() throws LifecycleException {
  
          // Validate and update our current state
          if (started)
              throw new LifecycleException
                  (sm.getString("coyoteConnector.alreadyStarted"));
          lifecycle.fireLifecycleEvent(START_EVENT, null);
          started = true;
  
      }
  
  
      /**
       * Terminate processing requests via this Connector.
       *
       * @exception LifecycleException if a fatal shutdown error occurs
       */
      public void stop() throws LifecycleException {
  
          // Validate and update our current state
          if (!started)
              throw new LifecycleException
                  (sm.getString("coyoteConnector.notStarted"));
          lifecycle.fireLifecycleEvent(STOP_EVENT, null);
          started = false;
  
          try {
              protocolHandler.destroy();
          } catch (Exception e) {
              throw new LifecycleException
                  (sm.getString
                   ("coyoteProcessor.processorDestroyFailed", e));
          }
  
      }
  
  
  }
  
  
  

--
To unsubscribe, e-mail:   <mailto:tomcat-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:tomcat-dev-help@jakarta.apache.org>


Mime
View raw message