You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by cr...@locus.apache.org on 2000/04/15 07:39:19 UTC
cvs commit: jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/util CookieUtil.java
craigmcc 00/04/14 22:39:19
Modified: proposals/catalina STATUS.html
proposals/catalina/src/share/org/apache/tomcat/connector/http
Constants.java HttpConnector.java
HttpProcessor.java HttpRequestImpl.java
LocalStrings.properties
Added: proposals/catalina/src/share/org/apache/tomcat/util
CookieUtil.java
Log:
Flesh out a basic Connector implementation that is reasonably HTTP/1.0
compliant. This is primarily intended for testing and development until
a complete HTTP/1.1 implementation is available.
Revision Changes Path
1.2 +2 -2 jakarta-tomcat/proposals/catalina/STATUS.html
Index: STATUS.html
===================================================================
RCS file: /home/cvs/jakarta-tomcat/proposals/catalina/STATUS.html,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- STATUS.html 2000/04/13 23:09:18 1.1
+++ STATUS.html 2000/04/15 05:39:13 1.2
@@ -115,7 +115,7 @@
<td align="center">High</td>
<td>Design and implement a high-performance Connector implementation
that fully supports HTTP/1.1 for use in stand-alone applications.
- [org.apache.tomcat.connector.http</td>
+ [org.apache.tomcat.connector.http11]</td>
<td>---</td>
</tr>
<tr>
@@ -427,7 +427,7 @@
<br>
<div align="center"><hr width="75%"><font size="2">
-$Id: STATUS.html,v 1.1 2000/04/13 23:09:18 craigmcc Exp $
+$Id: STATUS.html,v 1.2 2000/04/15 05:39:13 craigmcc Exp $
</font></div>
</body>
1.2 +4 -2 jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/connector/http/Constants.java
Index: Constants.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/connector/http/Constants.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Constants.java 2000/02/20 02:57:10 1.1
+++ Constants.java 2000/04/15 05:39:14 1.2
@@ -1,7 +1,7 @@
/*
- * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/connector/http/Constants.java,v 1.1 2000/02/20 02:57:10 craigmcc Exp $
- * $Revision: 1.1 $
- * $Date: 2000/02/20 02:57:10 $
+ * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/connector/http/Constants.java,v 1.2 2000/04/15 05:39:14 craigmcc Exp $
+ * $Revision: 1.2 $
+ * $Date: 2000/04/15 05:39:14 $
*
* ====================================================================
*
@@ -72,5 +72,7 @@
public final class Constants {
public static final String Package = "org.apache.tomcat.connector.http";
+ public static final String ServerInfo =
+ "Catalina/0.1";
}
1.5 +53 -23 jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/connector/http/HttpConnector.java
Index: HttpConnector.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/connector/http/HttpConnector.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- HttpConnector.java 2000/04/14 19:41:51 1.4
+++ HttpConnector.java 2000/04/15 05:39:15 1.5
@@ -1,7 +1,7 @@
/*
- * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/connector/http/HttpConnector.java,v 1.4 2000/04/14 19:41:51 craigmcc Exp $
- * $Revision: 1.4 $
- * $Date: 2000/04/14 19:41:51 $
+ * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/connector/http/HttpConnector.java,v 1.5 2000/04/15 05:39:15 craigmcc Exp $
+ * $Revision: 1.5 $
+ * $Date: 2000/04/15 05:39:15 $
*
* ====================================================================
*
@@ -336,12 +336,25 @@
/**
+ * Recycle the specified Processor.
+ *
+ * @param processor The processor to be recycled
+ */
+ void recycle(HttpProcessor processor) {
+
+ processors.push(processor);
+
+ }
+
+
+ /**
* Recycle the specified Request.
*
* @param request The request to be recycled
*/
void recycle(HttpRequest request) {
+ request.recycle();
requests.push(request);
}
@@ -354,6 +367,7 @@
*/
void recycle(HttpResponse response) {
+ response.recycle();
responses.push(response);
}
@@ -382,20 +396,46 @@
/**
+ * 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();
+ if (logger != null)
+ logger.log(threadName + " " + 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();
+ if (logger != null)
+ logger.log(threadName + " " + message, throwable);
+
+ }
+
+
+ /**
* Instantiate and return a new processor suitable for receiving
* and processing HTTP requests.
*/
private HttpProcessor newProcessor() {
- curProcessors++;
- HttpProcessor processor = new HttpProcessor(this);
+ HttpProcessor processor = new HttpProcessor(this, curProcessors++);
if (processor instanceof Lifecycle) {
try {
((Lifecycle) processor).start();
} catch (LifecycleException e) {
- Logger logger = container.getLogger();
- if (logger != null)
- logger.log(threadName + ".newProcessor", e);
+ log("newProcessor: ", e);
}
}
return (processor);
@@ -419,11 +459,8 @@
try {
socket = serverSocket.accept();
} catch (IOException e) {
- if (!stopped) {
- Logger logger = container.getLogger();
- if (logger != null)
- logger.log(threadName + ".accept", e);
- }
+ if (!stopped)
+ log("accept: ", e);
break;
}
@@ -431,10 +468,7 @@
HttpProcessor processor = createProcessor();
if (processor == null) {
try {
- Logger logger = container.getLogger();
- if (logger != null)
- logger.log(threadName +
- "select: No processor available");
+ log("select: No processor available");
socket.close();
} catch (IOException e) {
;
@@ -458,9 +492,7 @@
if (threadName == null)
setThreadName("HttpConnector[" + port + "]");
- Logger logger = container.getLogger();
- if (logger != null)
- logger.log(threadName + ": Starting");
+ log("Starting");
thread = new Thread(this, threadName);
thread.setDaemon(true);
@@ -474,9 +506,7 @@
*/
private void threadStop() {
- Logger logger = container.getLogger();
- if (logger != null)
- logger.log(threadName + ": Stopping");
+ log("Stopping");
stopped = true;
try {
1.3 +463 -12 jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/connector/http/HttpProcessor.java
Index: HttpProcessor.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/connector/http/HttpProcessor.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- HttpProcessor.java 2000/04/10 20:01:36 1.2
+++ HttpProcessor.java 2000/04/15 05:39:15 1.3
@@ -1,7 +1,7 @@
/*
- * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/connector/http/HttpProcessor.java,v 1.2 2000/04/10 20:01:36 craigmcc Exp $
- * $Revision: 1.2 $
- * $Date: 2000/04/10 20:01:36 $
+ * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/connector/http/HttpProcessor.java,v 1.3 2000/04/15 05:39:15 craigmcc Exp $
+ * $Revision: 1.3 $
+ * $Date: 2000/04/15 05:39:15 $
*
* ====================================================================
*
@@ -65,16 +65,26 @@
package org.apache.tomcat.connector.http;
+import java.io.InputStream;
import java.io.IOException;
+import java.io.OutputStream;
+import java.net.InetAddress;
import java.net.Socket;
+import java.util.NoSuchElementException;
+import java.util.StringTokenizer;
+import javax.servlet.ServletException;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletResponse;
import org.apache.tomcat.Connector;
import org.apache.tomcat.Container;
+import org.apache.tomcat.HttpRequest;
+import org.apache.tomcat.HttpResponse;
import org.apache.tomcat.Lifecycle;
import org.apache.tomcat.LifecycleEvent;
import org.apache.tomcat.LifecycleException;
import org.apache.tomcat.LifecycleListener;
-import org.apache.tomcat.Request;
-import org.apache.tomcat.Response;
+import org.apache.tomcat.Logger;
+import org.apache.tomcat.util.CookieUtil;
import org.apache.tomcat.util.LifecycleSupport;
import org.apache.tomcat.util.StringManager;
@@ -87,11 +97,11 @@
* the request. When the processor is completed, it will recycle itself.
*
* @author Craig R. McClanahan
- * @version $Revision: 1.2 $ $Date: 2000/04/10 20:01:36 $
+ * @version $Revision: 1.3 $ $Date: 2000/04/15 05:39:15 $
*/
final class HttpProcessor
- implements Lifecycle {
+ implements Lifecycle, Runnable {
// ----------------------------------------------------------- Constructors
@@ -101,12 +111,15 @@
* Construct a new HttpProcessor associated with the specified connector.
*
* @param connector HttpConnector that owns this processor
+ * @param id Identifier of this HttpProcessor (unique per connector)
*/
- public HttpProcessor(HttpConnector connector) {
+ public HttpProcessor(HttpConnector connector, int id) {
super();
this.connector = connector;
-
+ this.id = id;
+ request = (HttpRequest) connector.newRequest();
+ response = (HttpResponse) connector.newResponse();
}
@@ -120,23 +133,101 @@
/**
+ * The identifier of this processor, unique per connector.
+ */
+ private int id = 0;
+
+
+ /**
+ * The input stream associated with this request.
+ */
+ private InputStream input = null;
+
+
+ /**
* The lifecycle event support for this component.
*/
private LifecycleSupport lifecycle = new LifecycleSupport(this);
+ /**
+ * The output stream associated with this request.
+ */
+ private OutputStream output = null;
+
+
+ /**
+ * The HTTP request object we will pass to our associated container.
+ */
+ private HttpRequest request = null;
+
+
+ /**
+ * The HTTP response object we will pass to our associated container.
+ */
+ private HttpResponse response = null;
+
+
+ /**
+ * The string manager for this package.
+ */
+ protected StringManager sm =
+ StringManager.getManager(Constants.Package);
+
+
+ /**
+ * The socket we are currently processing a request for. If this is
+ * <code>null</code>, this processor is available.
+ */
+ private Socket socket = null;
+
+
+ /**
+ * 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;
+
+
+ /**
+ * The name to register for the background thread.
+ */
+ private String threadName = null;
+
+
+ /**
+ * The thread synchronization object.
+ */
+ private String threadSync = "";
+
+
// -------------------------------------------------------- Package Methods
/**
* Process an incoming TCP/IP connection on the specified socket. Any
* exception that occurs during processing must be logged and swallowed.
+ * <b>NOTE</b>: This method is called from our Connector's thread. We
+ * must assign it to our own thread so that multiple simultaneous
+ * requests can be handled.
*
* @param socket TCP socket to process
*/
void process(Socket socket) {
- ; // FIXME: process()
+ this.socket = socket;
+ notify();
}
@@ -144,6 +235,356 @@
// -------------------------------------------------------- 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 = connector.getContainer().getLogger();
+ if (logger != null)
+ logger.log(threadName + " " + 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 = connector.getContainer().getLogger();
+ if (logger != null)
+ logger.log(threadName + " " + message, throwable);
+
+ }
+
+
+ /**
+ * Parse and record the connection parameters related to this request.
+ *
+ * @exception IOException if an input/output error occurs
+ * @exception ServletException if a parsing error occurs
+ */
+ private void parseConnection() throws IOException, ServletException {
+
+ ((HttpRequestImpl) request).setInet(socket.getInetAddress());
+ request.setServerPort(connector.getPort());
+
+ }
+
+
+ /**
+ * Parse the incoming HTTP request headers, and set the appropriate
+ * request headers.
+ *
+ * @exception IOException if an input/output error occurs
+ * @exception ServletException if a parsing error occurs
+ */
+ private void parseHeaders() throws IOException, ServletException {
+
+ while (true) {
+
+ // Read the next header line
+ String line = read();
+ if ((line == null) || (line.length() < 1))
+ break;
+
+ // Parse the header name and value
+ int colon = line.indexOf(":");
+ if (colon < 0)
+ throw new ServletException
+ (sm.getString("httpProcessor.parseHeaders.colon"));
+ String name = line.substring(0, colon).trim();
+ String match = name.toLowerCase();
+ String value = line.substring(colon + 1).trim();
+
+ // Set the corresponding request headers
+ if (match.equals("authorization")) {
+ ; // FIXME -- do not want to include with regular headers
+ } else if (match.equals("cookie")) {
+ Cookie cookies[] = CookieUtil.parseCookieHeader(value);
+ for (int i = 0; i < cookies.length; i++)
+ request.addCookie(cookies[i]);
+ } else if (match.equals("content-length")) {
+ int n = -1;
+ try {
+ n = Integer.parseInt(value);
+ } catch (Exception e) {
+ throw new ServletException
+ (sm.getString("httpProcessor.parseHeaders.contentLength"));
+ }
+ request.setContentLength(n);
+ } else if (match.equals("content-type")) {
+ request.setContentType(value); // FIXME -- encoding?
+ } else if (match.equals("host")) {
+ int n = value.indexOf(":");
+ if (n < 0)
+ request.setServerName(value);
+ else {
+ request.setServerName(value.substring(0, n).trim());
+ int port = 80;
+ try {
+ port = Integer.parseInt(value.substring(n+1).trim());
+ } catch (Exception e) {
+ throw new ServletException
+ (sm.getString("httpProcessor.parseHeaders.portNumber"));
+ }
+ request.setServerPort(port);
+ }
+ } else {
+ request.addHeader(name, value);
+ }
+ }
+
+ }
+
+
+ /**
+ * Parse the incoming HTTP request and set the corresponding HTTP request
+ * properties.
+ *
+ * @exception IOException if an input/output error occurs
+ * @exception ServletException if a parsing error occurs
+ */
+ private void parseRequest() throws IOException, ServletException {
+
+ // Parse the incoming request line
+ String line = read();
+ StringTokenizer st = new StringTokenizer(line);
+
+ String method = null;
+ try {
+ method = st.nextToken();
+ } catch (NoSuchElementException e) {
+ method = null;
+ }
+
+ String uri = null;
+ try {
+ uri = st.nextToken();
+ ; // FIXME - URL decode the URI?
+ } catch (NoSuchElementException e) {
+ uri = null;
+ }
+
+ String protocol = null;
+ try {
+ protocol = st.nextToken();
+ } catch (NoSuchElementException e) {
+ protocol = "HTTP/0.9";
+ }
+
+ // Validate the incoming request line
+ if (method == null) {
+ throw new ServletException
+ (sm.getString("httpProcessor.parseRequest.method"));
+ } else if (uri == null) {
+ throw new ServletException
+ (sm.getString("httpProcessor.parseRequest.uri"));
+ }
+
+ // Set the corresponding request properties
+ ((HttpRequest) request).setMethod(method);
+ request.setProtocol(protocol);
+ ((HttpRequest) request).setRequestURI(uri);
+ request.setScheme("http");
+
+ }
+
+
+ /**
+ * Process an incoming HTTP request on the Socket that has been assigned
+ * to this Processor. Any exceptions that occur during processing must be
+ * swallowed and dealt with.
+ */
+ private void process() {
+
+ boolean ok = true;
+
+ // Construct and initialize the objects we will need
+ try {
+ input = socket.getInputStream();
+ request.setStream(input);
+ request.setResponse(response);
+ output = socket.getOutputStream();
+ response.setStream(output);
+ response.setRequest(request);
+ ((HttpServletResponse) response.getResponse()).setHeader
+ ("Server", Constants.ServerInfo);
+ } catch (Exception e) {
+ log("process.create", e);
+ ok = false;
+ }
+
+ // Parse the incoming request
+ try {
+ if (ok) {
+ parseConnection();
+ parseRequest();
+ if (!request.getRequest().getProtocol().startsWith("HTTP/0"))
+ parseHeaders();
+ }
+ } catch (Exception e) {
+ try {
+ log("process.parse", e);
+ ((HttpServletResponse) response.getResponse()).sendError
+ (HttpServletResponse.SC_BAD_REQUEST);
+ } catch (Exception f) {
+ ;
+ }
+ }
+
+ // Ask our Container to process this request
+ try {
+ if (ok) {
+ connector.getContainer().invoke(request, response);
+ }
+ } catch (ServletException e) {
+ log("process.invoke", e);
+ try {
+ ((HttpServletResponse) response.getResponse()).sendError
+ (HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ } catch (Exception f) {
+ ;
+ }
+ ok = false;
+ } catch (Throwable e) {
+ log("process.invoke", e);
+ try {
+ ((HttpServletResponse) response.getResponse()).sendError
+ (HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ } catch (Exception f) {
+ ;
+ }
+ ok = false;
+ }
+
+ // Finish up the handling of the request
+ try {
+ if (output != null)
+ output.flush();
+ } catch (IOException e) {
+ ;
+ }
+ try {
+ socket.close();
+ } catch (IOException e) {
+ ;
+ }
+ socket = null;
+
+ }
+
+
+ /**
+ * Read a line from the specified input stream, and strip off the
+ * trailing carriage return and newline (if any). Return the remaining
+ * characters that were read as a String.
+ *
+ * @returns The lline that was read, or <code>null</code> if end-of-file
+ * was encountered
+ *
+ * @exception IOException if an input/output error occurs
+ */
+ private String read() throws IOException {
+
+ StringBuffer sb = new StringBuffer();
+ while (true) {
+ int ch = input.read();
+ if (ch < 0) {
+ if (sb.length() == 0) {
+ return (null);
+ } else {
+ break;
+ }
+ } else if (ch == '\r') {
+ continue;
+ } else if (ch == '\n') {
+ break;
+ }
+ sb.append((char) ch);
+ }
+ return (sb.toString());
+
+ }
+
+
+ // ---------------------------------------------- Background Thread Methods
+
+
+ /**
+ * The background thread that listens for incoming TCP/IP connections and
+ * hands them off to an appropriate processor.
+ */
+ public void run() {
+
+ while (!stopped) {
+
+ // Wait for the next socket to be assigned
+ try {
+ wait();
+ } catch (InterruptedException e) {
+ ;
+ }
+ if (socket == null)
+ continue;
+
+ // Process the request from this socket
+ process();
+
+ // Finish up this request
+ request.recycle();
+ response.recycle();
+ connector.recycle(this);
+
+ }
+
+ threadSync.notifyAll();
+
+ }
+
+
+ /**
+ * Start the background processing thread.
+ */
+ private void threadStart() {
+
+ if (threadName == null)
+ threadName = connector.getThreadName() + "[" + id + "]";
+
+ log("Starting");
+
+ thread = new Thread(this, threadName);
+ thread.setDaemon(true);
+ thread.start();
+
+ }
+
+
+ /**
+ * Stop the background processing thread.
+ */
+ private void threadStop() {
+
+ log("Stopping");
+
+ stopped = true;
+ process(null);
+ try {
+ threadSync.wait(5000);
+ } catch (InterruptedException e) {
+ ;
+ }
+ thread = null;
+
+ }
+
+
// ------------------------------------------------------ Lifecycle Methods
@@ -178,9 +619,14 @@
*/
public void start() throws LifecycleException {
+ if (started)
+ throw new LifecycleException
+ (sm.getString("httpProcessor.start"));
+ started = true;
lifecycle.fireLifecycleEvent(START_EVENT, null);
- ; // FIXME: start()
+ threadStart();
+
}
@@ -191,8 +637,13 @@
*/
public void stop() throws LifecycleException {
+ if (!started)
+ throw new LifecycleException
+ (sm.getString("httpProcessor.stop"));
+ started = false;
lifecycle.fireLifecycleEvent(STOP_EVENT, null);
- ; // FIXME: stop()
+
+ threadStop();
}
1.2 +57 -3 jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/connector/http/HttpRequestImpl.java
Index: HttpRequestImpl.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/connector/http/HttpRequestImpl.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- HttpRequestImpl.java 2000/04/14 18:55:28 1.1
+++ HttpRequestImpl.java 2000/04/15 05:39:16 1.2
@@ -1,7 +1,7 @@
/*
- * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/connector/http/HttpRequestImpl.java,v 1.1 2000/04/14 18:55:28 craigmcc Exp $
- * $Revision: 1.1 $
- * $Date: 2000/04/14 18:55:28 $
+ * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/connector/http/HttpRequestImpl.java,v 1.2 2000/04/15 05:39:16 craigmcc Exp $
+ * $Revision: 1.2 $
+ * $Date: 2000/04/15 05:39:16 $
*
* ====================================================================
*
@@ -65,6 +65,7 @@
package org.apache.tomcat.connector.http;
+import java.net.InetAddress;
import org.apache.tomcat.connector.HttpRequestBase;
@@ -72,7 +73,7 @@
* Implementation of <b>HttpRequest</b> specific to the HTTP connector.
*
* @author Craig R. McClanahan
- * @version $Revision: 1.1 $ $Date: 2000/04/14 18:55:28 $
+ * @version $Revision: 1.2 $ $Date: 2000/04/15 05:39:16 $
*/
final class HttpRequestImpl
@@ -83,6 +84,12 @@
/**
+ * The InetAddress of the remote client of ths request.
+ */
+ protected InetAddress inet = null;
+
+
+ /**
* Descriptive information about this Request implementation.
*/
protected static final String info =
@@ -93,6 +100,30 @@
/**
+ * [Package Private] Return the InetAddress of the remote client of
+ * this request.
+ */
+ InetAddress getInet() {
+
+ return (inet);
+
+ }
+
+
+ /**
+ * [Package Private] Set the InetAddress of the remote client of
+ * this request.
+ *
+ * @param inet The new InetAddress
+ */
+ void setInet(InetAddress inet) {
+
+ this.inet = inet;
+
+ }
+
+
+ /**
* Return descriptive information about this Request implementation and
* the corresponding version number, in the format
* <code><description>/<version></code>.
@@ -108,12 +139,35 @@
/**
+ * Return the Internet Protocol (IP) address of the client that sent
+ * this request.
+ */
+ public String getRemoteAddr() {
+
+ return (inet.getHostAddress());
+
+ }
+
+
+ /**
+ * Return the fully qualified name of the client that sent this request,
+ * or the IP address of the client if the name cannot be determined.
+ */
+ public String getRemoteHost() {
+
+ return (inet.getHostName());
+
+ }
+
+
+ /**
* Release all object references, and initialize instance variables, in
* preparation for reuse of this object.
*/
public void recycle() {
super.recycle();
+ inet = null;
((HttpConnector) connector).recycle(this);
}
1.2 +7 -0 jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/connector/http/LocalStrings.properties
Index: LocalStrings.properties
===================================================================
RCS file: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/connector/http/LocalStrings.properties,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- LocalStrings.properties 2000/02/20 02:57:10 1.1
+++ LocalStrings.properties 2000/04/15 05:39:16 1.2
@@ -1,2 +1,9 @@
httpConnector.alreadyStarted=HTTP connector has already been started
httpConnector.notStarted=HTTP connector has not yet been started
+httpProcessor.parseHeaders.contentLength=Invalid 'Content-Length' header
+httpProcessor.parseHeaders.colon=Invalid HTTP header format
+httpProcessor.parseHeaders.portNumber=Invalid TCP/IP port number in 'Host' header
+httpProcessor.parseRequest.method=Missing HTTP request method
+httpProcessor.parseRequest.uri=Missing HTTP request URI
+httpProcessor.start=HTTP processor has already been started
+httpProcessor.stop=HTTP processor has already been stopped
1.1 jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/util/CookieUtil.java
Index: CookieUtil.java
===================================================================
/*
* $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/util/CookieUtil.java,v 1.1 2000/04/15 05:39:18 craigmcc Exp $
* $Revision: 1.1 $
* $Date: 2000/04/15 05:39:18 $
*
* ====================================================================
*
* 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.tomcat.util;
import java.util.StringTokenizer;
import java.util.Vector;
import javax.servlet.http.Cookie;
/**
* General purpose Cookie parsing and encoding utility methods.
*
* @author Craig R. McClanahan
* @version $Revision: 1.1 $ $Date: 2000/04/15 05:39:18 $
*/
public final class CookieUtil {
/**
* Parse a cookie header into an array of cookies according to RFC 2109.
*
* @param header Value of an HTTP "Cookie" header
*/
public static Cookie[] parseCookieHeader(String header) {
if ((header == null) || (header.length() < 1))
return (new Cookie[0]);
Vector cookieJar = new Vector();
StringTokenizer tokens = new StringTokenizer(header, ";");
while (tokens.hasMoreTokens()) {
try {
String token = tokens.nextToken();
int equals = token.indexOf("=");
if (equals > 0) {
String name = URLDecode(token.substring(0, equals).trim());
String value = URLDecode(token.substring(equals+1).trim());
cookieJar.addElement(new Cookie(name, value));
}
} catch (Throwable e) {
;
}
}
Cookie[] cookies = new Cookie[cookieJar.size()];
cookieJar.copyInto(cookies);
return (cookies);
}
/**
* Decode and return the specified URL-encoded String.
*
* @param str The url-encoded string
*
* @exception IllegalArgumentException if a '%' character is not followed
* by a valid 2-digit hexadecimal number
*/
public static String URLDecode(String str)
throws IllegalArgumentException {
if (str == null)
return (null);
StringBuffer dec = new StringBuffer();
int pos = 0;
int len = str.length();
dec.ensureCapacity(str.length());
while (pos < len) {
int lookahead; // Look-ahead position
// Look ahead to the next URLencoded metacharacter, if any
for (lookahead = pos; lookahead < len; lookahead++) {
char ch = str.charAt(lookahead);
if ((ch == '+') || (ch == '%'))
break;
}
// If there were non-metacharacters, copy them as a block
if (lookahead > pos) {
dec.append(str.substring(pos, lookahead));
pos = lookahead;
}
// Shortcut out if we are at the end of the string
if (pos >= len)
break;
// Process the next metacharacter
char meta = str.charAt(pos);
if (meta == '+') {
dec.append(' ');
pos++;
} else if (meta == '%') {
try {
dec.append((char) Integer.parseInt
(str.substring(pos+1, pos+3), 16));
} catch (NumberFormatException e) {
throw new IllegalArgumentException
("Invalid hexadecimal '" + str.substring(pos+1, pos+3)
+ " in URLencoded string");
} catch (StringIndexOutOfBoundsException e) {
throw new IllegalArgumentException
("Invalid unescaped '%' in URLcoded string");
}
pos += 3;
}
}
return (dec.toString());
}
}