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 2012/02/25 17:47:27 UTC

svn commit: r1293647 - in /httpcomponents/httpcore/trunk: ./ httpcore-nio/src/main/java/org/apache/http/nio/protocol/ httpcore-nio/src/test/java/org/apache/http/nio/integration/

Author: olegk
Date: Sat Feb 25 16:47:26 2012
New Revision: 1293647

URL: http://svn.apache.org/viewvc?rev=1293647&view=rev
Log:
HTTPCORE-289: HttpAsyncService fails to invoke Cancellable#cancel() when the ongoing HTTP exchange is aborted by the client

Added:
    httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncHandlerCancellable.java   (with props)
Modified:
    httpcomponents/httpcore/trunk/RELEASE_NOTES.txt
    httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncService.java
    httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncHandlers.java
    httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestPipelining.java

Modified: httpcomponents/httpcore/trunk/RELEASE_NOTES.txt
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/RELEASE_NOTES.txt?rev=1293647&r1=1293646&r2=1293647&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/RELEASE_NOTES.txt (original)
+++ httpcomponents/httpcore/trunk/RELEASE_NOTES.txt Sat Feb 25 16:47:26 2012
@@ -1,3 +1,11 @@
+Changes since 4.2-BETA1 
+-------------------
+
+* [HTTPCORE-289] HttpAsyncService fails to invoke Cancellable#cancel() when the ongoing HTTP 
+  exchange is aborted by the client. 
+  Contributed by Oleg Kalnichevski <olegk at apache.org>
+
+
 Release 4.2-BETA1
 -------------------
 

Modified: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncService.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncService.java?rev=1293647&r1=1293646&r2=1293647&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncService.java (original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncService.java Sat Feb 25 16:47:26 2012
@@ -356,12 +356,7 @@ public class HttpAsyncService implements
     }
 
     public void endOfInput(final NHttpServerConnection conn) throws IOException {
-        State state = ensureNotNull(getState(conn));
-        if (state.getResponseState().compareTo(MessageState.READY) > 0) {
-            conn.suspendInput();
-        } else {
-            conn.close();
-        }
+        conn.close();
     }
 
     public void timeout(final NHttpServerConnection conn) throws IOException {

Added: httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncHandlerCancellable.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncHandlerCancellable.java?rev=1293647&view=auto
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncHandlerCancellable.java (added)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncHandlerCancellable.java Sat Feb 25 16:47:26 2012
@@ -0,0 +1,153 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * 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/>.
+ *
+ */
+
+package org.apache.http.nio.integration;
+
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.http.HttpCoreNIOTestBase;
+import org.apache.http.HttpException;
+import org.apache.http.HttpRequest;
+import org.apache.http.LoggingClientConnectionFactory;
+import org.apache.http.LoggingServerConnectionFactory;
+import org.apache.http.concurrent.Cancellable;
+import org.apache.http.impl.DefaultConnectionReuseStrategy;
+import org.apache.http.impl.DefaultHttpResponseFactory;
+import org.apache.http.impl.nio.DefaultNHttpClientConnection;
+import org.apache.http.impl.nio.DefaultNHttpServerConnection;
+import org.apache.http.nio.NHttpConnectionFactory;
+import org.apache.http.nio.protocol.BasicAsyncRequestConsumer;
+import org.apache.http.nio.protocol.HttpAsyncExchange;
+import org.apache.http.nio.protocol.HttpAsyncRequestConsumer;
+import org.apache.http.nio.protocol.HttpAsyncRequestHandler;
+import org.apache.http.nio.protocol.HttpAsyncRequestHandlerRegistry;
+import org.apache.http.nio.protocol.HttpAsyncService;
+import org.apache.http.nio.reactor.IOReactorStatus;
+import org.apache.http.nio.reactor.ListenerEndpoint;
+import org.apache.http.params.HttpParams;
+import org.apache.http.protocol.HttpContext;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestHttpAsyncHandlerCancellable extends HttpCoreNIOTestBase {
+
+    @Before
+    public void setUp() throws Exception {
+        initServer();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        shutDownServer();
+    }
+
+    @Override
+    protected NHttpConnectionFactory<DefaultNHttpServerConnection> createServerConnectionFactory(
+            final HttpParams params) throws Exception {
+        return new LoggingServerConnectionFactory(params);
+    }
+
+    @Override
+    protected NHttpConnectionFactory<DefaultNHttpClientConnection> createClientConnectionFactory(
+            final HttpParams params) throws Exception {
+        return new LoggingClientConnectionFactory(params);
+    }
+
+    @Test
+    public void testRequestCancelled() throws Exception {
+        
+        final CountDownLatch latch = new CountDownLatch(1);
+        final Cancellable cancellable = new Cancellable() {
+            
+            public boolean cancel() {
+                latch.countDown();
+                return true;
+            }
+        };
+        
+        HttpAsyncRequestHandlerRegistry registry = new HttpAsyncRequestHandlerRegistry();
+        registry.register("*", new HttpAsyncRequestHandler<HttpRequest>() {
+
+            public HttpAsyncRequestConsumer<HttpRequest> processRequest(
+                    final HttpRequest request,
+                    final HttpContext context) throws HttpException, IOException {
+                return new BasicAsyncRequestConsumer();
+            }
+
+            public void handle(
+                    final HttpRequest data, 
+                    final HttpAsyncExchange httpExchange, 
+                    final HttpContext context)
+                    throws HttpException, IOException {
+                httpExchange.setCallback(cancellable);
+                // do not submit a response;
+            }
+            
+        });
+        HttpAsyncService serviceHandler = new HttpAsyncService(
+                this.serverHttpProc,
+                new DefaultConnectionReuseStrategy(),
+                new DefaultHttpResponseFactory(),
+                registry,
+                null,
+                this.serverParams);
+        this.server.start(serviceHandler);
+
+        ListenerEndpoint endpoint = this.server.getListenerEndpoint();
+        endpoint.waitFor();
+
+        Assert.assertEquals("Test server status", IOReactorStatus.ACTIVE, this.server.getStatus());
+        InetSocketAddress address = (InetSocketAddress) endpoint.getAddress();
+        Socket socket = new Socket("localhost", address.getPort());
+        try {
+            OutputStream outstream = socket.getOutputStream();
+            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outstream, "US-ASCII"));
+            writer.write("GET /long HTTP/1.1\r\n");
+            writer.write("Host: localhost\r\n");
+            writer.write("\r\n");
+            writer.flush();
+            
+            Thread.sleep(250);
+            
+            writer.close();
+        } finally {
+            socket.close();
+        }
+
+        Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
+    }
+
+}

Propchange: httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncHandlerCancellable.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncHandlerCancellable.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncHandlerCancellable.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncHandlers.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncHandlers.java?rev=1293647&r1=1293646&r2=1293647&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncHandlers.java (original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncHandlers.java Sat Feb 25 16:47:26 2012
@@ -54,17 +54,17 @@ import org.apache.http.message.BasicHttp
 import org.apache.http.nio.NHttpConnectionFactory;
 import org.apache.http.nio.entity.NStringEntity;
 import org.apache.http.nio.protocol.BasicAsyncRequestConsumer;
+import org.apache.http.nio.protocol.BasicAsyncRequestHandler;
 import org.apache.http.nio.protocol.BasicAsyncRequestProducer;
 import org.apache.http.nio.protocol.BasicAsyncResponseConsumer;
 import org.apache.http.nio.protocol.BasicAsyncResponseProducer;
-import org.apache.http.nio.protocol.BasicAsyncRequestHandler;
-import org.apache.http.nio.protocol.HttpAsyncRequestExecutor;
+import org.apache.http.nio.protocol.HttpAsyncExchange;
 import org.apache.http.nio.protocol.HttpAsyncExpectationVerifier;
 import org.apache.http.nio.protocol.HttpAsyncRequestConsumer;
+import org.apache.http.nio.protocol.HttpAsyncRequestExecutor;
 import org.apache.http.nio.protocol.HttpAsyncRequestHandler;
 import org.apache.http.nio.protocol.HttpAsyncRequestHandlerRegistry;
 import org.apache.http.nio.protocol.HttpAsyncRequestHandlerResolver;
-import org.apache.http.nio.protocol.HttpAsyncExchange;
 import org.apache.http.nio.protocol.HttpAsyncService;
 import org.apache.http.nio.reactor.IOReactorStatus;
 import org.apache.http.nio.reactor.ListenerEndpoint;

Modified: httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestPipelining.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestPipelining.java?rev=1293647&r1=1293646&r2=1293647&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestPipelining.java (original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestPipelining.java Sat Feb 25 16:47:26 2012
@@ -36,6 +36,8 @@ import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.net.InetSocketAddress;
 import java.net.Socket;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
 import org.apache.http.HttpCoreNIOTestBase;
 import org.apache.http.HttpException;
@@ -71,7 +73,6 @@ import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
-import org.mockito.Mockito;
 
 /**
  * Tests for handling pipelined requests.
@@ -178,80 +179,16 @@ public class TestPipelining extends Http
     }
 
     @Test
-    public void testBasicPipeliningHalfClosed() throws Exception {
-        HttpAsyncRequestHandlerRegistry registry = new HttpAsyncRequestHandlerRegistry();
-        registry.register("*", new BasicAsyncRequestHandler(new HttpRequestHandler() {
-
-            public void handle(
-                    final HttpRequest request,
-                    final HttpResponse response,
-                    final HttpContext context) throws HttpException, IOException {
-                String content = "thank you very much";
-                NStringEntity entity = NStringEntity.create(content, ContentType.DEFAULT_TEXT);
-                response.setEntity(entity);
-            }
-
-        }));
-        HttpAsyncService serviceHandler = new HttpAsyncService(
-                this.serverHttpProc,
-                new DefaultConnectionReuseStrategy(),
-                registry,
-                this.serverParams);
-        this.server.start(serviceHandler);
-
-        ListenerEndpoint endpoint = this.server.getListenerEndpoint();
-        endpoint.waitFor();
-
-        Assert.assertEquals("Test server status", IOReactorStatus.ACTIVE, this.server.getStatus());
-
-        InetSocketAddress address = (InetSocketAddress) endpoint.getAddress();
-        Socket socket = new Socket("localhost", address.getPort());
-        try {
-            OutputStream outstream = socket.getOutputStream();
-            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outstream, "US-ASCII"));
-            writer.write("GET / HTTP/1.1\r\n");
-            writer.write("Host: localhost\r\n");
-            writer.write("\r\n");
-            writer.write("GET / HTTP/1.1\r\n");
-            writer.write("Host: localhost\r\n");
-            writer.write("\r\n");
-            writer.flush();
-            socket.shutdownOutput();
-            InputStream instream = socket.getInputStream();
-            BufferedReader reader = new BufferedReader(new InputStreamReader(instream, "US-ASCII"));
-            StringBuilder buf = new StringBuilder();
-            char[] tmp = new char[1024];
-            int l;
-            while ((l = reader.read(tmp)) != -1) {
-                buf.append(tmp, 0, l);
-            }
-            reader.close();
-            writer.close();
-            String expected =
-                    "HTTP/1.1 200 OK\r\n" +
-                    "Server: TEST-SERVER/1.1\r\n" +
-                    "Content-Length: 19\r\n" +
-                    "Content-Type: text/plain; charset=ISO-8859-1\r\n" +
-                    "\r\n" +
-                    "thank you very much" +
-                    "HTTP/1.1 200 OK\r\n" +
-                    "Server: TEST-SERVER/1.1\r\n" +
-                    "Content-Length: 19\r\n" +
-                    "Content-Type: text/plain; charset=ISO-8859-1\r\n" +
-                    "\r\n" +
-                    "thank you very much";
-            Assert.assertEquals(expected, buf.toString());
-
-        } finally {
-            socket.close();
-        }
-
-    }
-
-    @Test
     public void testPipeliningWithCancellable() throws Exception {
 
-        final Cancellable cancellable = Mockito.mock(Cancellable.class);
+        final CountDownLatch latch = new CountDownLatch(1);
+        final Cancellable cancellable = new Cancellable() {
+            
+            public boolean cancel() {
+                latch.countDown();
+                return true;
+            }
+        };
 
         HttpAsyncRequestHandlerRegistry registry = new HttpAsyncRequestHandlerRegistry();
         registry.register("/long", new HttpAsyncRequestHandler<HttpRequest>() {
@@ -332,7 +269,7 @@ public class TestPipelining extends Http
             socket.close();
         }
 
-        Mockito.verify(cancellable).cancel();
+        Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
     }
 
 }