hc-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ol...@apache.org
Subject svn commit: r509149 - in /jakarta/httpcomponents/httpcore/trunk: module-main/src/main/java/org/apache/http/protocol/ module-nio/src/main/java/org/apache/http/nio/protocol/ module-nio/src/main/java/org/apache/http/nio/util/
Date Mon, 19 Feb 2007 10:35:50 GMT
Author: olegk
Date: Mon Feb 19 02:35:49 2007
New Revision: 509149

URL: http://svn.apache.org/viewvc?view=rev&rev=509149
Log:
HTTPCORE-42: ThrottlingHttpServiceHandler can now correctly handle expectation failures when
the expectation verifier returns a non 1xx response. Minor cleanups in HttpService class

Modified:
    jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/HttpService.java
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/ThrottlingHttpServiceHandler.java
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/util/SharedOutputBuffer.java

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=509149&r1=509148&r2=509149
==============================================================================
--- 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
Mon Feb 19 02:35:49 2007
@@ -46,7 +46,9 @@
 import org.apache.http.MethodNotSupportedException;
 import org.apache.http.ProtocolException;
 import org.apache.http.UnsupportedHttpVersionException;
+import org.apache.http.entity.ByteArrayEntity;
 import org.apache.http.params.HttpParams;
+import org.apache.http.util.EncodingUtils;
 
 /**
  * Minimalistic server-side implementation of an HTTP processor.
@@ -172,11 +174,11 @@
         response = this.responseFactory.newHttpResponse(ver, HttpStatus.SC_OK, context);
         response.getParams().setDefaults(this.params);
         
+        context.setAttribute(HttpExecutionContext.HTTP_REQUEST, request);
+        context.setAttribute(HttpExecutionContext.HTTP_RESPONSE, response);
+
         try {
             this.processor.process(request, context);
-
-            context.setAttribute(HttpExecutionContext.HTTP_REQUEST, request);
-            context.setAttribute(HttpExecutionContext.HTTP_RESPONSE, response);
             doService(request, response, context);
             
             if (request instanceof HttpEntityEnclosingRequest) {
@@ -212,6 +214,10 @@
         } else {
             response.setStatusCode(HttpStatus.SC_INTERNAL_SERVER_ERROR);
         }
+        byte[] msg = EncodingUtils.getAsciiBytes(ex.getMessage());
+        ByteArrayEntity entity = new ByteArrayEntity(msg);
+        entity.setContentType("text/plain; charset=US-ASCII");
+        response.setEntity(entity);
     }
     
     protected void doService(

Modified: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/ThrottlingHttpServiceHandler.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/ThrottlingHttpServiceHandler.java?view=diff&rev=509149&r1=509148&r2=509149
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/ThrottlingHttpServiceHandler.java
(original)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/ThrottlingHttpServiceHandler.java
Mon Feb 19 02:35:49 2007
@@ -32,6 +32,7 @@
 package org.apache.http.nio.protocol;
 
 import java.io.IOException;
+import java.io.InterruptedIOException;
 import java.io.OutputStream;
 import java.net.InetAddress;
 
@@ -239,47 +240,12 @@
         HttpContext context = conn.getContext();
         HttpRequest request = conn.getHttpRequest();
 
-        HttpVersion ver = request.getRequestLine().getHttpVersion();
-        if (!ver.lessEquals(HttpVersion.HTTP_1_1)) {
-            // Downgrade protocol version if greater than HTTP/1.1 
-            ver = HttpVersion.HTTP_1_1;
-        }
-
         final ServerConnState connState = (ServerConnState) context.getAttribute(CONN_STATE);
 
         connState.resetInput();
         connState.setRequest(request);
         connState.setInputState(ServerConnState.REQUEST_RECEIVED);
 
-        if (request instanceof HttpEntityEnclosingRequest) {
-            HttpEntityEnclosingRequest entityReq = (HttpEntityEnclosingRequest) request;
-            
-            if (entityReq.expectContinue()) {
-                try {
-                    HttpResponse ack = this.responseFactory.newHttpResponse(
-                            ver, HttpStatus.SC_CONTINUE, context);
-                    ack.getParams().setDefaults(this.params);
-                    if (this.expectationVerifier != null) {
-                        this.expectationVerifier.verify(request, ack, context);
-                    }
-                    conn.submitResponse(ack);
-                } catch (HttpException ex) {
-                    shutdownConnection(conn);
-                    if (this.eventListener != null) {
-                        this.eventListener.fatalProtocolException(ex);
-                    }
-                    return;
-                }
-            }
-            
-            // Create a wrapper entity instead of the original one
-            if (entityReq.getEntity() != null) {
-                entityReq.setEntity(new BufferedContent(
-                        entityReq.getEntity(), 
-                        connState.getInbuffer()));
-            }
-        }
-        
         this.executor.execute(new Runnable() {
             
             public void run() {
@@ -406,13 +372,41 @@
         }
     }
     
+    private void waitForOutput(
+            final ServerConnState connState, 
+            int expectedState) throws InterruptedIOException {
+        synchronized (connState) {
+            try {
+                for (;;) {
+                    int currentState = connState.getOutputState();
+                    if (currentState == expectedState) {
+                        break;
+                    }
+                    if (currentState == ServerConnState.SHUTDOWN) {
+                        throw new InterruptedIOException("Service interrupted");
+                    }
+                    connState.wait();
+                }
+            } catch (InterruptedException ex) {
+                connState.shutdown();
+            }
+        }
+    }
+    
     private void handleException(
             final ServerConnState connState,
             final HttpException ex,
             final HttpContext context) throws HttpException, IOException {
 
         HttpRequest request = connState.getRequest();
+        context.setAttribute(HttpExecutionContext.HTTP_REQUEST, request);
         
+        HttpVersion ver;
+        if (request != null) {
+            ver = request.getRequestLine().getHttpVersion(); 
+        } else {
+            ver = HttpVersion.HTTP_1_0;
+        }
         int code = HttpStatus.SC_INTERNAL_SERVER_ERROR;
         if (ex instanceof MethodNotSupportedException) {
             code = HttpStatus.SC_NOT_IMPLEMENTED;
@@ -421,20 +415,19 @@
         } else if (ex instanceof ProtocolException) {
             code = HttpStatus.SC_BAD_REQUEST;
         }
-
-        HttpVersion ver;
-        if (request != null) {
-            ver = request.getRequestLine().getHttpVersion(); 
-        } else {
-            ver = HttpVersion.HTTP_1_0;
-        }
-        HttpResponse response =  this.responseFactory.newHttpResponse(ver, code, context);
+        
+        HttpResponse response =  this.responseFactory.newHttpResponse(
+                ver, 
+                code, 
+                context);
 
         byte[] msg = EncodingUtils.getAsciiBytes(ex.getMessage());
         ByteArrayEntity entity = new ByteArrayEntity(msg);
         entity.setContentType("text/plain; charset=US-ASCII");
         response.setEntity(entity);
 
+        context.setAttribute(HttpExecutionContext.HTTP_RESPONSE, response);
+
         this.httpProcessor.process(response, context);
         
         connState.setResponse(response);
@@ -445,6 +438,8 @@
             final HttpContext context) throws HttpException, IOException {
 
         HttpRequest request = connState.getRequest();
+        context.setAttribute(HttpExecutionContext.HTTP_REQUEST, request);
+
         HttpVersion ver = request.getRequestLine().getHttpVersion();
 
         if (!ver.lessEquals(HttpVersion.HTTP_1_1)) {
@@ -452,10 +447,58 @@
             ver = HttpVersion.HTTP_1_1;
         }
 
-        HttpResponse response = this.responseFactory.newHttpResponse(ver, HttpStatus.SC_OK,
context);
+        HttpResponse response;
+
+        if (request instanceof HttpEntityEnclosingRequest) {
+            HttpEntityEnclosingRequest entityReq = (HttpEntityEnclosingRequest) request;
+            
+            if (entityReq.expectContinue()) {
+                response = this.responseFactory.newHttpResponse(
+                        ver, 
+                        HttpStatus.SC_CONTINUE, 
+                        context);
+                response.getParams().setDefaults(this.params);
+                if (this.expectationVerifier != null) {
+                    try {
+                        this.expectationVerifier.verify(request, response, context);
+                    } catch (HttpException ex) {
+                        handleException(connState, ex ,context);
+                        return;
+                    }
+                }
+            
+                if (response.getStatusLine().getStatusCode() < 200) {
+                    // Send 1xx response indicating the server expections
+                    // have been met
+                    waitForOutput(connState, ServerConnState.READY);
+                    connState.setResponse(response);
+                    synchronized (connState) {
+                        waitForOutput(connState, ServerConnState.RESPONSE_SENT);
+                        connState.resetOutput();
+                    }
+                } else {
+                    // The request does not meet the server expections
+                    context.setAttribute(HttpExecutionContext.HTTP_RESPONSE, response);
+                    this.httpProcessor.process(response, context);
+                    connState.setResponse(response);
+                    return;
+                }
+            }
+
+            // Create a wrapper entity instead of the original one
+            if (entityReq.getEntity() != null) {
+                entityReq.setEntity(new BufferedContent(
+                        entityReq.getEntity(), 
+                        connState.getInbuffer()));
+            }
+        }
+
+        response = this.responseFactory.newHttpResponse(
+                ver, 
+                HttpStatus.SC_OK, 
+                context);
         response.getParams().setDefaults(this.params);
-        
-        context.setAttribute(HttpExecutionContext.HTTP_REQUEST, request);
+
         context.setAttribute(HttpExecutionContext.HTTP_RESPONSE, response);
         
         try {
@@ -487,32 +530,12 @@
             final ServerConnState connState,
             final ContentIOControl ioControl) throws IOException, HttpException {
 
-        // Make sure the connection is ready for output
-        // (the previous worker thread terminated)
-        synchronized (connState) {
-            try {
-                for (;;) {
-                    int currentState = connState.getOutputState();
-                    if (currentState == ServerConnState.READY) {
-                        break;
-                    }
-                    if (currentState == ServerConnState.SHUTDOWN) {
-                        break;
-                    }
-                    connState.wait();
-                }
-            } catch (InterruptedException ex) {
-                connState.shutdown();
-            }
-            if (connState.getOutputState() == ServerConnState.SHUTDOWN) {
-                return;
-            }
-        }
+        waitForOutput(connState, ServerConnState.READY);
         
         // Response is ready to be committed
         HttpResponse response = connState.getResponse();
-        
-        int expectedSate;
+
+        int terminalState;
         if (response.getEntity() != null) {
             ContentOutputBuffer buffer = connState.getOutbuffer();
             OutputStream outstream = new ContentOutputStream(buffer);
@@ -521,31 +544,14 @@
             entity.writeTo(outstream);
             outstream.flush();
             outstream.close();
-            expectedSate = ServerConnState.RESPONSE_BODY_DONE;
+            terminalState = ServerConnState.RESPONSE_BODY_DONE;
         } else {
             ioControl.requestOutput();
-            expectedSate = ServerConnState.RESPONSE_SENT;
+            terminalState = ServerConnState.RESPONSE_SENT;
         }
-        
-        // and wait until the I/O thread completes sending the
-        // response and the connection state transitions to the 
-        // expected state
         synchronized (connState) {
-            try {
-                for (;;) {
-                    int currentState = connState.getOutputState();
-                    if (currentState == expectedSate) {
-                        break;
-                    }
-                    if (currentState == ServerConnState.SHUTDOWN) {
-                        break;
-                    }
-                    connState.wait();
-                }
-                connState.resetOutput();
-            } catch (InterruptedException ex) {
-                connState.shutdown();
-            }
+            waitForOutput(connState, terminalState);
+            connState.resetOutput();
         }
     }
     

Modified: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/util/SharedOutputBuffer.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/util/SharedOutputBuffer.java?view=diff&rev=509149&r1=509148&r2=509149
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/util/SharedOutputBuffer.java
(original)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/util/SharedOutputBuffer.java
Mon Feb 19 02:35:49 2007
@@ -113,7 +113,6 @@
         }
         synchronized (this.mutex) {
             if (this.shutdown || this.state == CLOSING || this.state == CLOSED) {
-                System.err.println("state: " + this.state);
                 throw new IllegalStateException("Buffer already closed for writing");
             }
             this.state = STREAMING;



Mime
View raw message