hc-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ol...@apache.org
Subject svn commit: r230707 - in /jakarta/httpclient/trunk/coyote-httpconnector/src/java/org/apache/http/coyote: ./ impl/
Date Sun, 07 Aug 2005 22:07:32 GMT
Author: olegk
Date: Sun Aug  7 15:07:25 2005
New Revision: 230707

URL: http://svn.apache.org/viewcvs?rev=230707&view=rev
Log:
Coyote API proved to be more intrusive than I initially anticipated. The initial architecture
has been heavily refactored to allow for callbacks from the container to the connector via
the action hook interface

Removed:
    jakarta/httpclient/trunk/coyote-httpconnector/src/java/org/apache/http/coyote/HttpService.java
    jakarta/httpclient/trunk/coyote-httpconnector/src/java/org/apache/http/coyote/impl/CoyoteHttpService.java
    jakarta/httpclient/trunk/coyote-httpconnector/src/java/org/apache/http/coyote/impl/CoyoteObjectConverter.java
Modified:
    jakarta/httpclient/trunk/coyote-httpconnector/src/java/org/apache/http/coyote/HttpProtocolHandler.java
    jakarta/httpclient/trunk/coyote-httpconnector/src/java/org/apache/http/coyote/impl/DefaultHttpConnectionManager.java
    jakarta/httpclient/trunk/coyote-httpconnector/src/java/org/apache/http/coyote/impl/HttpConnectionProcessor.java

Modified: jakarta/httpclient/trunk/coyote-httpconnector/src/java/org/apache/http/coyote/HttpProtocolHandler.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/coyote-httpconnector/src/java/org/apache/http/coyote/HttpProtocolHandler.java?rev=230707&r1=230706&r2=230707&view=diff
==============================================================================
--- jakarta/httpclient/trunk/coyote-httpconnector/src/java/org/apache/http/coyote/HttpProtocolHandler.java
(original)
+++ jakarta/httpclient/trunk/coyote-httpconnector/src/java/org/apache/http/coyote/HttpProtocolHandler.java
Sun Aug  7 15:07:25 2005
@@ -39,7 +39,6 @@
 import org.apache.commons.logging.LogFactory;
 import org.apache.coyote.Adapter;
 import org.apache.coyote.ProtocolHandler;
-import org.apache.http.coyote.impl.CoyoteHttpService;
 import org.apache.http.coyote.impl.DefaultHttpConnectionFactory;
 import org.apache.http.coyote.impl.DefaultHttpConnectionManager;
 import org.apache.http.coyote.params.CoyoteParams;
@@ -114,9 +113,10 @@
                 this.minThreads, this.maxThreads,
                 0L, TimeUnit.MILLISECONDS,
                 new LinkedBlockingQueue<Runnable>());
-        this.connmanager = new DefaultHttpConnectionManager(
-                new CoyoteHttpService(this.adapter, this.params), 
-                this.requestExecutor); 
+        this.connmanager = new DefaultHttpConnectionManager( 
+                this.requestExecutor,
+                this.params,
+                this.adapter); 
         this.listenerExecutor = new ThreadPoolExecutor(
                 1, 1,
                 0L, TimeUnit.MILLISECONDS,

Modified: jakarta/httpclient/trunk/coyote-httpconnector/src/java/org/apache/http/coyote/impl/DefaultHttpConnectionManager.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/coyote-httpconnector/src/java/org/apache/http/coyote/impl/DefaultHttpConnectionManager.java?rev=230707&r1=230706&r2=230707&view=diff
==============================================================================
--- jakarta/httpclient/trunk/coyote-httpconnector/src/java/org/apache/http/coyote/impl/DefaultHttpConnectionManager.java
(original)
+++ jakarta/httpclient/trunk/coyote-httpconnector/src/java/org/apache/http/coyote/impl/DefaultHttpConnectionManager.java
Sun Aug  7 15:07:25 2005
@@ -36,11 +36,12 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.coyote.Adapter;
 import org.apache.http.HttpServerConnection;
 import org.apache.http.coyote.HttpConnectionManager;
-import org.apache.http.coyote.HttpService;
 import org.apache.http.coyote.IOProcessingListener;
 import org.apache.http.coyote.IOProcessor;
+import org.apache.http.params.HttpParams;
 
 /**
  * <p>
@@ -54,21 +55,27 @@
     private static Log LOG = LogFactory.getLog(DefaultHttpConnectionManager.class);
     
     private final Executor executor;
-    private final HttpService service;
+    private final HttpParams params;
+    private final Adapter adapter;
     private final List<IOProcessor> processors;
     
     public DefaultHttpConnectionManager(
-            final HttpService service,
-            final Executor executor) {
+    		final Executor executor, 
+    		final HttpParams params,
+    		final Adapter adapter) {
         super();
-        if (service == null) {
-            throw new IllegalArgumentException("Http service may not be null");
-        }
         if (executor == null) {
             throw new IllegalArgumentException("Executor may not be null");
         }
+        if (params == null) {
+            throw new IllegalArgumentException("HTTP parameters may not be null");
+        }
+        if (adapter == null) {
+            throw new IllegalArgumentException("Coyote adapter may not be null");
+        }
         this.executor = executor;
-        this.service = service;
+        this.params = params;
+        this.adapter = adapter;
         this.processors = new LinkedList<IOProcessor>();
     }
 
@@ -113,7 +120,7 @@
             
         };
         HttpConnectionProcessor processor = new HttpConnectionProcessor(
-                conn, this.service, listener);
+                conn, this.params, this.adapter, listener);
         addProcessor(processor);
         this.executor.execute(processor);
     }

Modified: jakarta/httpclient/trunk/coyote-httpconnector/src/java/org/apache/http/coyote/impl/HttpConnectionProcessor.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/coyote-httpconnector/src/java/org/apache/http/coyote/impl/HttpConnectionProcessor.java?rev=230707&r1=230706&r2=230707&view=diff
==============================================================================
--- jakarta/httpclient/trunk/coyote-httpconnector/src/java/org/apache/http/coyote/impl/HttpConnectionProcessor.java
(original)
+++ jakarta/httpclient/trunk/coyote-httpconnector/src/java/org/apache/http/coyote/impl/HttpConnectionProcessor.java
Sun Aug  7 15:07:25 2005
@@ -30,20 +30,40 @@
 package org.apache.http.coyote.impl;
 
 import java.io.IOException;
+import java.net.InetAddress;
 import java.net.SocketTimeoutException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.UnknownHostException;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.coyote.ActionCode;
+import org.apache.coyote.ActionHook;
+import org.apache.coyote.Adapter;
+import org.apache.coyote.Request;
+import org.apache.coyote.Response;
 import org.apache.http.ConnectionClosedException;
+import org.apache.http.Header;
 import org.apache.http.HttpException;
+import org.apache.http.HttpMutableResponse;
 import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
 import org.apache.http.HttpServerConnection;
-import org.apache.http.coyote.HttpService;
+import org.apache.http.HttpStatus;
+import org.apache.http.HttpVersion;
+import org.apache.http.MethodNotSupportedException;
+import org.apache.http.ProtocolException;
+import org.apache.http.RequestLine;
 import org.apache.http.coyote.IOProcessingListener;
 import org.apache.http.coyote.IOProcessor;
+import org.apache.http.coyote.MalformedURIException;
+import org.apache.http.coyote.UnsupportedHttpVersionException;
+import org.apache.http.coyote.params.CoyoteParams;
 import org.apache.http.impl.BasicHttpResponse;
 import org.apache.http.impl.ConnectionReuseStrategy;
 import org.apache.http.impl.DefaultConnectionReuseStrategy;
+import org.apache.http.params.HttpParams;
 
 /**
  * <p>
@@ -52,37 +72,67 @@
  *
  * @version $Revision$
  */
-public class HttpConnectionProcessor implements IOProcessor {
+public class HttpConnectionProcessor implements IOProcessor, ActionHook {
 
     private static Log LOG = LogFactory.getLog(HttpConnectionProcessor.class);
 	
     private volatile boolean destroyed = false;
     
     private final HttpServerConnection conn;
-    private final HttpService service;
+    private final HttpParams params;
+    private final Adapter adapter;
     private final IOProcessingListener listener;
+
+    private final Request coyotereq;
+    private final Response coyoteres;
+    
+    private HttpRequest httpreq = null;
+    private HttpResponse httpres = null;
     
     public HttpConnectionProcessor(
             final HttpServerConnection conn,
-    		final HttpService service,
+            final HttpParams params,
+            final Adapter adapter,
             final IOProcessingListener listener) {
     	super();
         if (conn == null) {
             throw new IllegalArgumentException("HTTP connection may not be null");
         }
-        if (service == null) {
-            throw new IllegalArgumentException("HTTP service may not be null");
+        if (params == null) {
+            throw new IllegalArgumentException("HTTP parameters may not be null");
+        }
+        if (adapter == null) {
+            throw new IllegalArgumentException("Coyote adapter may not be null");
         }
         this.conn = conn;
-        this.service = service;
+        this.params = params;
+        this.adapter = adapter;
         this.listener = listener;
+        
+        this.coyotereq = new Request();
+        this.coyoteres = new Response();
+        this.coyoteres.setHook(this);
+        this.coyoteres.setRequest(this.coyotereq);
     }
 
     public void run() {
         try {
             while (this.conn.isOpen() && !Thread.interrupted()) {
                 try {
-                    process();
+                	try {
+                        receiveHttpRequest();
+                        prepareCoyoteRequest();
+                        callServletContainer();
+                        sendHttpResponse();
+                    	manageHttpConnection();
+                	} catch (HttpException ex) {
+                		LOG.debug("Malformed HTTP requst");
+                		this.httpres = processHttpException(ex);
+                		sendHttpResponse();
+                	}
+                } catch (ConnectionClosedException ex) {
+                	LOG.debug("Client closed connection");
+                    break;
                 } catch (SocketTimeoutException ex) {
                     LOG.debug("Socket timeout");
                     break;
@@ -102,41 +152,135 @@
         }
     }
 
-    private void process() throws IOException {
-        BasicHttpResponse response = new BasicHttpResponse();
+    private void receiveHttpRequest() throws IOException, HttpException {
+    	this.httpreq = this.conn.receiveRequest(this.params);
+        LOG.debug("HTTP request received");
+    }
+
+    private HttpResponse processHttpException(final HttpException ex) {
+    	LOG.debug("Processing HTTP exception");
+    	HttpMutableResponse response = new BasicHttpResponse();
+    	response.getParams().setDefaults(this.params);
+        if (ex instanceof MethodNotSupportedException) {
+            response.setStatusCode(HttpStatus.SC_NOT_IMPLEMENTED);
+        } else if (ex instanceof ProtocolException) {
+            response.setStatusCode(HttpStatus.SC_BAD_REQUEST);
+        } else {
+            response.setStatusCode(HttpStatus.SC_INTERNAL_SERVER_ERROR);
+        }
+        response.setHeader(new Header("Server", "Jakarta HttpCommons"));
+        response.setHeader(new Header("Connection", "Close"));
+        return response;
+    }
+        
+    private void sendHttpResponse() throws IOException {
+    	try {
+    		this.conn.sendResponse(this.httpres);
+            LOG.debug("HTTP response sent");
+    	} catch (HttpException ex) {
+    		LOG.error("Malformed HTTP response", ex);
+    		this.conn.close();
+    	}
+    }
+
+    private void prepareCoyoteRequest() throws HttpException {
+        // Convert the request line
+        RequestLine reqline = this.httpreq.getRequestLine();
+        HttpVersion ver = reqline.getHttpVersion();
+        if (!ver.lessEquals(HttpVersion.HTTP_1_1)) {
+            throw new UnsupportedHttpVersionException("Unsupported verion: " + ver); 
+        }
+        this.coyotereq.method().setString(reqline.getMethod());
+        this.coyotereq.unparsedURI().setString(reqline.getUri());
+        
+        // Parse the request URI
+        URI uri = null;
         try {
-            HttpRequest request = this.conn.receiveRequest(this.service.getParams());
-            LOG.debug("HTTP request received");
-            this.service.process(request, response);
-        } catch (ConnectionClosedException ex) {
-        	LOG.debug("Client closed connection");
-            this.conn.close();
-            return;
-        } catch (HttpException ex) {
-            this.service.process(ex, response);
-        } catch (IOException ex) {
-        	LOG.warn("I/O error receiving HTTP request", ex);
-            this.conn.close();
-            return;
+            uri = new URI(reqline.getUri());
+        } catch (URISyntaxException ex) {
+            throw new MalformedURIException("Malformed URI: " + reqline.getUri(), ex);
         }
+        if (uri.isAbsolute()) {
+            // Absolute request URI. Ignore the 'host' header 
+        	this.coyotereq.scheme().setString(uri.getScheme());
+        	this.coyotereq.serverName().setString(uri.getHost());
+            int port = uri.getPort();
+            if (port < 0) {
+            	port = 80;
+            }
+            this.coyotereq.setServerPort(port);
+        } else {
+            // Relative request URI. Parse the 'host' header 
+        	this.coyotereq.scheme().setString("http");
+            Header header = httpreq.getFirstHeader("host");
+            if (header != null) {
+                String s = header.getValue();
+                int i = s.lastIndexOf(':');
+                if (i != -1) {
+                	this.coyotereq.serverName().setString(s.substring(0, i));
+                    try {
+                    	this.coyotereq.setServerPort(Integer.parseInt(s.substring(i + 1)));
+                    } catch (NumberFormatException ex) {
+                        throw new ProtocolException("Invalid target host: " + s); 
+                    }
+                } else {
+                	this.coyotereq.serverName().setString(s);
+                }
+            } else {
+                if (ver.greaterEquals(HttpVersion.HTTP_1_1)) {
+                    throw new ProtocolException("Target host not known"); 
+                }
+                // HTTP/1.0 compatibility
+                // User the default host and port values 
+                String defaulthost = null;
+                try {
+                    InetAddress localhost = InetAddress.getLocalHost();
+                    defaulthost = localhost.getHostName();
+                } catch (UnknownHostException ex) {
+                    defaulthost = "localhost";
+                }
+                this.coyotereq.setLocalHost(defaulthost);
+                this.coyotereq.serverName().setString(defaulthost);
+                this.coyotereq.setServerPort(CoyoteParams.getPort(httpreq.getParams()));
+            }
+        }
+        this.coyotereq.requestURI().setString(uri.getPath());
+        if (uri.getQuery() != null) {
+        	this.coyotereq.queryString().setString(uri.getQuery());
+        }
+        this.coyotereq.protocol().setString(ver.toString());
+
+        // Convert the request headers
+        Header[] headers = httpreq.getAllHeaders();
+        for (Header header: headers) {
+        	this.coyotereq.getMimeHeaders().addValue(header.getName()).setString(header.getValue());
+        }
+    }
+        
+    private void callServletContainer() throws IOException, HttpException {
         try {
-            this.conn.sendResponse(response);
-            LOG.debug("HTTP response sent");
-        } catch (HttpException ex) {
-        	LOG.debug("Malformed HTTP response: " + ex.getMessage());
-            this.conn.close();
+            this.adapter.service(this.coyotereq, this.coyoteres);
         } catch (IOException ex) {
-        	LOG.warn("I/O error sending HTTP response", ex);
-            this.conn.close();
-            return;
-        }
-        ConnectionReuseStrategy connreuse = new DefaultConnectionReuseStrategy();
-        if (!connreuse.keepAlive(response)) {
-            this.conn.close();
-        	LOG.debug("Connection closed");
-        } else {
-        	LOG.debug("Connection kept alive");
+        	throw ex;
+        } catch (Exception ex) {
+        	throw new HttpException(ex.getMessage(), ex);
         }
+	}
+
+    private void manageHttpConnection() throws IOException {
+    	if (this.conn.isOpen()) {
+            ConnectionReuseStrategy connreuse = new DefaultConnectionReuseStrategy();
+            if (!connreuse.keepAlive(this.httpres)) {
+                this.conn.close();
+            	LOG.debug("Connection closed");
+            } else {
+            	LOG.debug("Connection kept alive");
+            }
+    	}
+        this.coyotereq.recycle();
+        this.coyoteres.recycle();
+    	this.httpreq = null;
+    	this.httpres = null;
     }
     
     public void close() throws IOException {
@@ -156,4 +300,8 @@
         return this.destroyed;
     }
 	           
+	public void action(final ActionCode actionCode, final Object param) {
+		// Process callbacks from the container
+	}
+    
 }



Mime
View raw message