You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2006/09/08 17:22:40 UTC

svn commit: r441533 - in /jakarta/httpcomponents/httpcore/trunk: module-main/src/examples/org/apache/http/examples/ module-main/src/main/java/org/apache/http/protocol/ module-nio/src/examples/org/apache/http/nio/examples/

Author: olegk
Date: Fri Sep  8 08:22:39 2006
New Revision: 441533

URL: http://svn.apache.org/viewvc?view=rev&rev=441533
Log:
* Refactored HttpService to be more state-less. HttpService now takes HttpServerConnection and HttpContext as parameters to the #handleRequest method
* No more ugly logging methods in HttpService
* Fatal I/O and protocol exceptions are now propagated to the caller of the #handleRequest method

Modified:
    jakarta/httpcomponents/httpcore/trunk/module-main/src/examples/org/apache/http/examples/ElementalHttpServer.java
    jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/HttpService.java
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/examples/org/apache/http/nio/examples/AsyncHttpServerServer.java

Modified: jakarta/httpcomponents/httpcore/trunk/module-main/src/examples/org/apache/http/examples/ElementalHttpServer.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-main/src/examples/org/apache/http/examples/ElementalHttpServer.java?view=diff&rev=441533&r1=441532&r2=441533
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-main/src/examples/org/apache/http/examples/ElementalHttpServer.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-main/src/examples/org/apache/http/examples/ElementalHttpServer.java Fri Sep  8 08:22:39 2006
@@ -38,6 +38,7 @@
 import java.net.Socket;
 import java.net.URLDecoder;
 
+import org.apache.http.ConnectionClosedException;
 import org.apache.http.HttpException;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpResponse;
@@ -82,21 +83,24 @@
     
     static class HttpFileService extends HttpService {
         
-        public HttpFileService(final HttpServerConnection conn, final HttpContext context) {
-            super(conn, context);
+        public HttpFileService() {
+            super();
             addInterceptor(new ResponseDate());
             addInterceptor(new ResponseServer());                    
             addInterceptor(new ResponseContent());
             addInterceptor(new ResponseConnControl());
         }
 
-        protected void doService(final HttpRequest request, final HttpResponse response) 
-                throws HttpException, IOException {
+        protected void doService(
+                final HttpRequest request, 
+                final HttpResponse response,
+                final HttpContext context) throws HttpException, IOException {
+
             String method = request.getRequestLine().getMethod();
             if (!method.equalsIgnoreCase("GET") && !method.equalsIgnoreCase("HEAD")) {
                 throw new MethodNotSupportedException(method + " method not supported"); 
             }
-            String docroot = (String) getContext().getAttribute("server.docroot");
+            String docroot = (String) context.getAttribute("server.docroot");
             
             String target = request.getRequestLine().getUri();
             
@@ -149,18 +153,6 @@
             }
         }
         
-        protected void logMessage(final String s) {
-            System.out.println(s);
-        }
-        
-        protected void logIOException(final IOException ex) {
-            System.err.println("IO error: " + ex.getMessage());
-        }
-        
-        protected void logProtocolException(final HttpException ex) {
-            System.err.println("HTTP protocol error: " + ex.getMessage());
-        }
-        
     }
     
     static class RequestListenerThread extends Thread {
@@ -192,15 +184,12 @@
                     System.out.println("Incoming connection from " + socket.getInetAddress());
                     conn.bind(socket, this.params);
 
-                    // Set up local HTTP context
-                    HttpContext context = new HttpExecutionContext(this.globalContext);
-
                     // Set up HTTP service
-                    HttpFileService fileServiceHandler = new HttpFileService(conn, context);
+                    HttpFileService fileServiceHandler = new HttpFileService();
                     fileServiceHandler.setParams(this.params);
                     
                     // Start worker thread
-                    Thread t = new WorkerThread(fileServiceHandler);
+                    Thread t = new WorkerThread(fileServiceHandler, conn, this.globalContext);
                     t.setDaemon(true);
                     t.start();
                 } catch (InterruptedIOException ex) {
@@ -217,20 +206,35 @@
     static class WorkerThread extends Thread {
 
         private final HttpService httpservice;
+        private final HttpServerConnection conn;
+        private final HttpContext context;
         
-        public WorkerThread(final HttpService httpservice) {
+        public WorkerThread(
+                final HttpService httpservice, 
+                final HttpServerConnection conn, 
+                final HttpContext parentContext) {
             super();
             this.httpservice = httpservice;
+            this.conn = conn;
+            this.context = new HttpExecutionContext(parentContext);
         }
         
         public void run() {
             System.out.println("New connection thread");
             try {
-                while (!this.httpservice.isDestroyed() && this.httpservice.isActive()) {
-                    this.httpservice.handleRequest();
+                while (!Thread.interrupted() && this.conn.isOpen()) {
+                    this.httpservice.handleRequest(this.conn, this.context);
                 }
+            } catch (ConnectionClosedException ex) {
+                System.err.println("Client closed connection");
+            } catch (IOException ex) {
+                System.err.println("I/O error: " + ex.getMessage());
+            } catch (HttpException ex) {
+                System.err.println("Unrecoverable HTTP protocol violation: " + ex.getMessage());
             } finally {
-                this.httpservice.destroy();
+                try {
+                    this.conn.shutdown();
+                } catch (IOException ignore) {}
             }
         }
 

Modified: jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/HttpService.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/HttpService.java?view=diff&rev=441533&r1=441532&r2=441533
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/HttpService.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/HttpService.java Fri Sep  8 08:22:39 2006
@@ -31,7 +31,6 @@
 
 import java.io.IOException;
 
-import org.apache.http.ConnectionClosedException;
 import org.apache.http.ConnectionReuseStrategy;
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpEntityEnclosingRequest;
@@ -58,26 +57,12 @@
  */
 public class HttpService extends AbstractHttpProcessor {
 
-    private final HttpServerConnection conn;
-    private final HttpContext context;
-
-    private volatile boolean destroyed = false;
-    
     private HttpParams params = null;
     private ConnectionReuseStrategy connStrategy = null;
     private HttpResponseFactory responseFactory = null;
 
-    public HttpService(final HttpServerConnection conn) {
-        this(conn, null);
-    }
-
-    public HttpService(final HttpServerConnection conn, final HttpContext parentContext) {
+    public HttpService() {
         super();
-        if (conn == null) {
-            throw new IllegalArgumentException("HTTP server connection may not be null");
-        }
-        this.conn = conn;
-        this.context = new HttpExecutionContext(parentContext);
         this.connStrategy = new DefaultConnectionReuseStrategy();
         this.responseFactory = new DefaultHttpResponseFactory();
     }
@@ -96,10 +81,6 @@
         this.responseFactory = responseFactory;
     }
     
-    public HttpContext getContext() {
-        return this.context;
-    }
-
     public HttpParams getParams() {
         return this.params;
     }
@@ -108,31 +89,12 @@
         this.params = params;
     }
     
-    public boolean isActive() {
-        return this.conn.isOpen();
-    }
-    
-    protected void closeConnection() {
-        try {
-            this.conn.close();
-        } catch (IOException ex) {
-            logIOException(ex);
-        }
-    }
-            
-    protected void shutdownConnection() {
-        try {
-            this.conn.shutdown();
-        } catch (IOException ex) {
-            logIOException(ex);
-        }
-    }
-            
-    public void handleRequest() { 
-        this.context.setAttribute(HttpExecutionContext.HTTP_CONNECTION, this.conn);
+    public void handleRequest(final HttpServerConnection conn, final HttpContext context) 
+            throws IOException, HttpException { 
+        context.setAttribute(HttpExecutionContext.HTTP_CONNECTION, conn);
         HttpResponse response;
         try {
-            HttpRequest request = this.conn.receiveRequestHeader(this.params);
+            HttpRequest request = conn.receiveRequestHeader(this.params);
             HttpVersion ver = request.getRequestLine().getHttpVersion();
             if (!ver.lessEquals(HttpVersion.HTTP_1_1)) {
                 // Downgrade protocol version if greater than HTTP/1.1 
@@ -144,22 +106,18 @@
             
             if (request instanceof HttpEntityEnclosingRequest) {
                 if (((HttpEntityEnclosingRequest) request).expectContinue()) {
-
-                    logMessage("Expected 100 (Continue)");
-                    
                     HttpResponse ack = this.responseFactory.newHttpResponse(ver, HttpStatus.SC_CONTINUE);
                     ack.getParams().setDefaults(this.params);
-                    this.conn.sendResponseHeader(ack);
-                    this.conn.flush();
+                    conn.sendResponseHeader(ack);
+                    conn.flush();
                 }
-                this.conn.receiveRequestEntity((HttpEntityEnclosingRequest) request);
+                conn.receiveRequestEntity((HttpEntityEnclosingRequest) request);
             }
-            preprocessRequest(request, this.context);
-            logMessage("Request received");
+            preprocessRequest(request, context);
 
-            this.context.setAttribute(HttpExecutionContext.HTTP_REQUEST, request);
-            this.context.setAttribute(HttpExecutionContext.HTTP_RESPONSE, response);
-            doService(request, response);
+            context.setAttribute(HttpExecutionContext.HTTP_REQUEST, request);
+            context.setAttribute(HttpExecutionContext.HTTP_RESPONSE, response);
+            doService(request, response, context);
             
             if (request instanceof HttpEntityEnclosingRequest) {
                 // Make sure the request content is fully consumed
@@ -168,39 +126,18 @@
                     entity.consumeContent();
                 }
             }
-        } catch (ConnectionClosedException ex) {
-            logMessage("Client closed connection");
-            shutdownConnection();
-            return;
         } catch (HttpException ex) {
             response = this.responseFactory.newHttpResponse(HttpVersion.HTTP_1_0, 
                     HttpStatus.SC_INTERNAL_SERVER_ERROR);
             response.getParams().setDefaults(this.params);
             handleException(ex, response);
-        } catch (IOException ex) {
-            logIOException(ex);
-            shutdownConnection();
-            return;
-        }
-        try {
-            postprocessResponse(response, this.context);
-            this.conn.sendResponseHeader(response);
-            this.conn.sendResponseEntity(response);
-            this.conn.flush();
-            logMessage("Response sent");
-        } catch (HttpException ex) {
-            logProtocolException(ex);
-            closeConnection();
-            return;
-        } catch (IOException ex) {
-            logIOException(ex);
-            shutdownConnection();
-            return;
         }
-        if (!this.connStrategy.keepAlive(response, this.context)) {
-            closeConnection();
-        } else {
-            logMessage("Connection kept alive");
+        postprocessResponse(response, context);
+        conn.sendResponseHeader(response);
+        conn.sendResponseEntity(response);
+        conn.flush();
+        if (!this.connStrategy.keepAlive(response, context)) {
+            conn.close();
         }
     }
     
@@ -216,31 +153,11 @@
         }
     }
     
-    protected void doService(final HttpRequest request, final HttpResponse response) 
-            throws HttpException, IOException {
+    protected void doService(
+            final HttpRequest request, 
+            final HttpResponse response,
+            final HttpContext context) throws HttpException, IOException {
         response.setStatusCode(HttpStatus.SC_NOT_IMPLEMENTED);
     }
     
-    protected void logMessage(final String s) {
-    }
-    
-    protected void logIOException(final IOException ex) {
-    }
-    
-    protected void logProtocolException(final HttpException ex) {
-    }
-    
-    public void destroy() {
-        this.destroyed = true;
-        try {
-            this.conn.shutdown();
-        } catch (IOException ex) {
-            logIOException(ex);
-        }
-    }
-    
-    public boolean isDestroyed() {
-        return this.destroyed;
-    }
-               
 }

Modified: jakarta/httpcomponents/httpcore/trunk/module-nio/src/examples/org/apache/http/nio/examples/AsyncHttpServerServer.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/examples/org/apache/http/nio/examples/AsyncHttpServerServer.java?view=diff&rev=441533&r1=441532&r2=441533
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/examples/org/apache/http/nio/examples/AsyncHttpServerServer.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/examples/org/apache/http/nio/examples/AsyncHttpServerServer.java Fri Sep  8 08:22:39 2006
@@ -9,6 +9,7 @@
 import java.net.SocketTimeoutException;
 import java.net.URLDecoder;
 
+import org.apache.http.ConnectionClosedException;
 import org.apache.http.HttpConnection;
 import org.apache.http.HttpException;
 import org.apache.http.HttpRequest;
@@ -31,6 +32,7 @@
 import org.apache.http.params.HttpParams;
 import org.apache.http.params.HttpProtocolParams;
 import org.apache.http.protocol.HttpContext;
+import org.apache.http.protocol.HttpExecutionContext;
 import org.apache.http.protocol.HttpService;
 import org.apache.http.protocol.ResponseConnControl;
 import org.apache.http.protocol.ResponseContent;
@@ -93,10 +95,10 @@
             session.setAttribute(CONSUMER, conn.getIOConsumer());
             session.setAttribute(PRODUCER, conn.getIOProducer());
             
-            HttpFileService service = new HttpFileService(conn, this.context);
+            HttpFileService service = new HttpFileService();
             service.setParams(this.params);
             
-            Thread worker = new WorkerThread(service);
+            Thread worker = new WorkerThread(service, conn, this.context);
             session.setAttribute(WORKER, worker);
 
             worker.setDaemon(true);
@@ -143,21 +145,24 @@
     
     static class HttpFileService extends HttpService {
         
-        public HttpFileService(final HttpServerConnection conn, final HttpContext context) {
-            super(conn, context);
+        public HttpFileService() {
+            super();
             addInterceptor(new ResponseDate());
             addInterceptor(new ResponseServer());                    
             addInterceptor(new ResponseContent());
             addInterceptor(new ResponseConnControl());
         }
 
-        protected void doService(final HttpRequest request, final HttpResponse response) 
-                throws HttpException, IOException {
+        protected void doService(
+                final HttpRequest request, 
+                final HttpResponse response,
+                final HttpContext context) throws HttpException, IOException {
+
             String method = request.getRequestLine().getMethod();
             if (!method.equalsIgnoreCase("GET") && !method.equalsIgnoreCase("HEAD")) {
                 throw new MethodNotSupportedException(method + " method not supported"); 
             }
-            String docroot = (String) getContext().getAttribute("server.docroot");
+            String docroot = (String) context.getAttribute("server.docroot");
             
             String target = request.getRequestLine().getUri();
             
@@ -210,37 +215,40 @@
             }
         }
         
-        protected void logMessage(final String s) {
-            System.out.println(s);
-        }
-        
-        protected void logIOException(final IOException ex) {
-            System.err.println("IO error: " + ex.getMessage());
-        }
-        
-        protected void logProtocolException(final HttpException ex) {
-            System.err.println("HTTP protocol error: " + ex.getMessage());
-        }
-        
     }
     
     static class WorkerThread extends Thread {
 
         private final HttpService httpservice;
+        private final HttpServerConnection conn;
+        private final HttpContext context;
         
-        public WorkerThread(final HttpService httpservice) {
+        public WorkerThread(
+                final HttpService httpservice, 
+                final HttpServerConnection conn, 
+                final HttpContext parentContext) {
             super();
             this.httpservice = httpservice;
+            this.conn = conn;
+            this.context = new HttpExecutionContext(parentContext);
         }
         
         public void run() {
             System.out.println("New connection thread");
             try {
-                while (!this.httpservice.isDestroyed() && this.httpservice.isActive()) {
-                    this.httpservice.handleRequest();
+                while (!Thread.interrupted() && this.conn.isOpen()) {
+                    this.httpservice.handleRequest(this.conn, this.context);
                 }
+            } catch (ConnectionClosedException ex) {
+                System.err.println("Client closed connection");
+            } catch (IOException ex) {
+                System.err.println("I/O error: " + ex.getMessage());
+            } catch (HttpException ex) {
+                System.err.println("Unrecoverable HTTP protocol violation: " + ex.getMessage());
             } finally {
-                this.httpservice.destroy();
+                try {
+                    this.conn.shutdown();
+                } catch (IOException ignore) {}
             }
         }