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 2008/03/08 01:20:23 UTC

svn commit: r634873 - in /httpcomponents/httpcore/trunk/module-nio/src: main/java/org/apache/http/impl/nio/ main/java/org/apache/http/nio/protocol/ test/java/org/apache/http/nio/protocol/

Author: olegk
Date: Fri Mar  7 16:20:15 2008
New Revision: 634873

URL: http://svn.apache.org/viewvc?rev=634873&view=rev
Log:
HTTPCORE-154: Fixed handling of requests with a null entity 
Contributed by Sam Berlin <sberlin at gmail.com>

Modified:
    httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpClientConnection.java
    httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/AsyncNHttpClientHandler.java
    httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/nio/protocol/TestAsyncNHttpHandlers.java

Modified: httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpClientConnection.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpClientConnection.java?rev=634873&r1=634872&r2=634873&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpClientConnection.java (original)
+++ httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpClientConnection.java Fri Mar  7 16:20:15 2008
@@ -205,7 +205,8 @@
         this.requestWriter.write(request);
         this.hasBufferedOutput = this.outbuf.hasData();
 
-        if (request instanceof HttpEntityEnclosingRequest) {
+        if (request instanceof HttpEntityEnclosingRequest
+                && ((HttpEntityEnclosingRequest) request).getEntity() != null) {
             prepareEncoder(request);
             this.request = request;
         }

Modified: httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/AsyncNHttpClientHandler.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/AsyncNHttpClientHandler.java?rev=634873&r1=634872&r2=634873&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/AsyncNHttpClientHandler.java (original)
+++ httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/AsyncNHttpClientHandler.java Fri Mar  7 16:20:15 2008
@@ -143,29 +143,32 @@
 
             context.setAttribute(ExecutionContext.HTTP_REQUEST, request);
             this.httpProcessor.process(request, context);
+            
+            HttpEntityEnclosingRequest entityReq = null;
+            HttpEntity entity = null;
+            
+            if (request instanceof HttpEntityEnclosingRequest) {
+                entityReq = (HttpEntityEnclosingRequest) request;
+                entity = entityReq.getEntity();
+            }
+
+            if (entity instanceof ProducingNHttpEntity) {
+                connState.setProducingEntity((ProducingNHttpEntity) entity);
+            } else if (entity != null) {
+                connState.setProducingEntity(new NHttpEntityWrapper(entity));
+            }
+            
             connState.setRequest(request);
             conn.submitRequest(request);
             connState.setOutputState(ClientConnState.REQUEST_SENT);
 
-            if (request instanceof HttpEntityEnclosingRequest) {
-                HttpEntityEnclosingRequest entityReq = (HttpEntityEnclosingRequest) request;
-                HttpEntity entity = entityReq.getEntity();
-                if (entity != null) {
-                    if (entity instanceof ProducingNHttpEntity) {
-                        connState.setProducingEntity((ProducingNHttpEntity) entity);
-                    } else {
-                        connState.setProducingEntity(new NHttpEntityWrapper(entity));
-                    }
-                }
-
-                if (entityReq.expectContinue()) {
-                    int timeout = conn.getSocketTimeout();
-                    connState.setTimeout(timeout);
-                    timeout = this.params.getIntParameter(
-                            CoreProtocolPNames.WAIT_FOR_CONTINUE, 3000);
-                    conn.setSocketTimeout(timeout);
-                    connState.setOutputState(ClientConnState.EXPECT_CONTINUE);
-                }
+            if (entityReq != null && entityReq.expectContinue()) {
+                int timeout = conn.getSocketTimeout();
+                connState.setTimeout(timeout);
+                timeout = this.params.getIntParameter(
+                        CoreProtocolPNames.WAIT_FOR_CONTINUE, 3000);
+                conn.setSocketTimeout(timeout);
+                connState.setOutputState(ClientConnState.EXPECT_CONTINUE);
             }
 
         } catch (IOException ex) {

Modified: httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/nio/protocol/TestAsyncNHttpHandlers.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/nio/protocol/TestAsyncNHttpHandlers.java?rev=634873&r1=634872&r2=634873&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/nio/protocol/TestAsyncNHttpHandlers.java (original)
+++ httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/nio/protocol/TestAsyncNHttpHandlers.java Fri Mar  7 16:20:15 2008
@@ -1759,4 +1759,130 @@
         this.server.shutdown();
 
     }
+    
+    /**
+     * This test case executes a series of simple (non-pipelined) POST requests
+     * with no entities on the client side, to ensure they are sent properly,
+     * and the server can read them.
+     */
+    public void testHttpPostWithNoEntities() throws Exception {
+
+        final int connNo = 3;
+        final int reqNo = 20;
+        final RequestCount requestCount = new RequestCount(connNo * reqNo);
+
+        NHttpRequestHandler requestHandler = new SimpleNHttpRequestHandler() {
+
+            public ConsumingNHttpEntity entityRequest(
+                    final HttpEntityEnclosingRequest request,
+                    final HttpContext context) throws HttpException, IOException {
+                return new BufferingNHttpEntity(
+                        request.getEntity(),
+                        new HeapByteBufferAllocator());
+            }
+
+            public void handle(
+                    final HttpRequest request,
+                    final HttpResponse response,
+                    final HttpContext context) throws HttpException, IOException {
+                if (request instanceof HttpEntityEnclosingRequest) {
+                    HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity();
+                    byte[] b = EntityUtils.toByteArray(entity);
+                    if(b.length != 0)
+                        response.setEntity(new NStringEntity("Error!"));
+                    else
+                        response.setEntity(null);
+                } else {
+                    response.setEntity(null);
+                }
+            }
+        };
+
+        NHttpRequestExecutionHandler requestExecutionHandler = new NHttpRequestExecutionHandler() {
+
+            public void initalizeContext(final HttpContext context, final Object attachment) {
+                context.setAttribute("REQ-COUNT", new Integer(0));
+                context.setAttribute("RES-COUNT", new Integer(0));
+            }
+
+            public void finalizeContext(final HttpContext context) {
+            }
+
+            public ConsumingNHttpEntity responseEntity(
+                    final HttpResponse response,
+                    final HttpContext context) throws IOException {
+                return new BufferingNHttpEntity(response.getEntity(),
+                        new HeapByteBufferAllocator());
+            }
+
+            public HttpRequest submitRequest(final HttpContext context) {
+                int i = ((Integer) context.getAttribute("REQ-COUNT")).intValue();
+                BasicHttpEntityEnclosingRequest post = null;
+                if (i < reqNo) {
+                    post = new BasicHttpEntityEnclosingRequest("POST", "/?" + i);
+                    context.setAttribute("REQ-COUNT", new Integer(i + 1));
+                }
+                return post;
+            }
+
+            public void handleResponse(final HttpResponse response, final HttpContext context) {
+                NHttpConnection conn = (NHttpConnection) context.getAttribute(
+                        ExecutionContext.HTTP_CONNECTION);
+
+                int i = ((Integer) context.getAttribute("RES-COUNT")).intValue();
+                i++;
+                context.setAttribute("RES-COUNT", new Integer(i));
+
+                try {
+                    HttpEntity entity = response.getEntity();
+                    byte[] data = EntityUtils.toByteArray(entity);
+                    if(data.length > 0)
+                        requestCount.abort();
+                    else
+                        requestCount.decrement();
+                } catch (IOException ex) {
+                    requestCount.abort();
+                    return;
+                }
+
+                if (i < reqNo) {
+                    conn.requestInput();
+                }
+            }
+
+        };
+
+        NHttpServiceHandler serviceHandler = createHttpServiceHandler(
+                requestHandler,
+                null);
+
+        NHttpClientHandler clientHandler = createHttpClientHandler(
+                requestExecutionHandler);
+
+        this.server.setRequestCount(requestCount);
+        this.client.setRequestCount(requestCount);
+        
+        this.server.start(serviceHandler);
+        this.client.start(clientHandler);
+        
+        
+
+        ListenerEndpoint endpoint = this.server.getListenerEndpoint();
+        endpoint.waitFor();
+        
+        InetSocketAddress serverAddress = (InetSocketAddress) endpoint.getAddress();
+
+        for (int i = 0; i < connNo; i++) {
+            this.client.openConnection(
+                    new InetSocketAddress("localhost", serverAddress.getPort()),
+                    null);
+        }
+
+        requestCount.await(10000);
+        assertEquals(0, requestCount.getValue());
+
+        this.client.shutdown();
+        this.server.shutdown();
+
+    }
 }