hc-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ol...@apache.org
Subject svn commit: r1658391 - in /httpcomponents/httpcore/trunk/httpcore-nio/src: main/java/org/apache/http/impl/nio/ test/java/org/apache/http/nio/integration/
Date Mon, 09 Feb 2015 12:55:38 GMT
Author: olegk
Date: Mon Feb  9 12:55:37 2015
New Revision: 1658391

URL: http://svn.apache.org/r1658391
Log:
Non-blocking connection should not trigger end-of-stream callback as long as there is still
data in the session input buffer

Modified:
    httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpClientConnection.java
    httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpServerConnection.java
    httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncHandlersPipelining.java

Modified: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpClientConnection.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpClientConnection.java?rev=1658391&r1=1658390&r2=1658391&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpClientConnection.java
(original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpClientConnection.java
Mon Feb  9 12:55:37 2015
@@ -199,7 +199,7 @@ public class DefaultNHttpClientConnectio
                         resetInput();
                     }
                 }
-                if (bytesRead == -1) {
+                if (bytesRead == -1 && !this.inbuf.hasData()) {
                     handler.endOfInput(this);
                 }
             }

Modified: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpServerConnection.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpServerConnection.java?rev=1658391&r1=1658390&r2=1658391&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpServerConnection.java
(original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpServerConnection.java
Mon Feb  9 12:55:37 2015
@@ -204,7 +204,7 @@ public class DefaultNHttpServerConnectio
                         resetInput();
                     }
                 }
-                if (bytesRead == -1) {
+                if (bytesRead == -1 && !this.inbuf.hasData()) {
                     handler.endOfInput(this);
                 }
             }

Modified: httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncHandlersPipelining.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncHandlersPipelining.java?rev=1658391&r1=1658390&r2=1658391&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncHandlersPipelining.java
(original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncHandlersPipelining.java
Mon Feb  9 12:55:37 2015
@@ -29,37 +29,47 @@ package org.apache.http.nio.integration;
 
 import java.io.IOException;
 import java.net.InetSocketAddress;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
 import java.util.Queue;
 import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 
+import org.apache.http.ConnectionClosedException;
 import org.apache.http.HttpException;
+import org.apache.http.HttpHeaders;
 import org.apache.http.HttpHost;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpResponse;
 import org.apache.http.HttpStatus;
 import org.apache.http.HttpVersion;
 import org.apache.http.entity.ContentType;
+import org.apache.http.entity.StringEntity;
 import org.apache.http.message.BasicHttpRequest;
 import org.apache.http.message.BasicHttpResponse;
 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.HttpAsyncExchange;
 import org.apache.http.nio.protocol.HttpAsyncExpectationVerifier;
 import org.apache.http.nio.protocol.HttpAsyncRequestConsumer;
 import org.apache.http.nio.protocol.HttpAsyncRequestHandler;
 import org.apache.http.nio.protocol.HttpAsyncRequestHandlerMapper;
+import org.apache.http.nio.protocol.HttpAsyncRequestProducer;
+import org.apache.http.nio.protocol.HttpAsyncResponseConsumer;
 import org.apache.http.nio.protocol.UriHttpAsyncRequestHandlerMapper;
 import org.apache.http.nio.reactor.IOReactorStatus;
 import org.apache.http.nio.reactor.ListenerEndpoint;
 import org.apache.http.nio.testserver.HttpCoreNIOTestBase;
 import org.apache.http.protocol.HttpContext;
 import org.apache.http.protocol.HttpProcessor;
+import org.apache.http.protocol.HttpRequestHandler;
 import org.apache.http.protocol.ImmutableHttpProcessor;
 import org.apache.http.protocol.RequestConnControl;
 import org.apache.http.protocol.RequestContent;
@@ -349,4 +359,84 @@ public class TestHttpAsyncHandlersPipeli
         }
     }
 
+    @Test
+    public void testUnexpectedConnectionClosure() throws Exception {
+        final UriHttpAsyncRequestHandlerMapper registry = new UriHttpAsyncRequestHandlerMapper();
+        registry.register("*", new BasicAsyncRequestHandler(new HttpRequestHandler() {
+
+            @Override
+            public void handle(
+                    final HttpRequest request,
+                    final HttpResponse response,
+                    final HttpContext context) throws HttpException, IOException {
+                response.setStatusCode(HttpStatus.SC_OK);
+                response.setEntity(new StringEntity("all is well", ContentType.TEXT_PLAIN));
+            }
+
+        }));
+        registry.register("/boom", new BasicAsyncRequestHandler(new HttpRequestHandler()
{
+
+            @Override
+            public void handle(
+                    final HttpRequest request,
+                    final HttpResponse response,
+                    final HttpContext context) throws HttpException, IOException {
+                response.setStatusCode(HttpStatus.SC_INTERNAL_SERVER_ERROR);
+                response.setHeader(HttpHeaders.CONNECTION, "Close");
+                response.setEntity(new StringEntity("boooooom!!!!!", ContentType.TEXT_PLAIN));
+            }
+
+        }));
+        final HttpHost target = start(registry, null);
+
+        this.client.setMaxPerRoute(3);
+        this.client.setMaxTotal(3);
+
+        for (int i = 0; i < 20; i++) {
+
+            final HttpAsyncRequestProducer p1 = new BasicAsyncRequestProducer(target, new
BasicHttpRequest("GET", "/"));
+            final HttpAsyncRequestProducer p2 = new BasicAsyncRequestProducer(target, new
BasicHttpRequest("GET", "/"));
+            final HttpAsyncRequestProducer p3 = new BasicAsyncRequestProducer(target, new
BasicHttpRequest("GET", "/boom"));
+            final HttpAsyncRequestProducer p4 = new BasicAsyncRequestProducer(target, new
BasicHttpRequest("GET", "/"));
+            final HttpAsyncRequestProducer p5 = new BasicAsyncRequestProducer(target, new
BasicHttpRequest("GET", "/"));
+            final List<HttpAsyncRequestProducer> requestProducers = new ArrayList<HttpAsyncRequestProducer>();
+            requestProducers.add(p1);
+            requestProducers.add(p2);
+            requestProducers.add(p3);
+            requestProducers.add(p4);
+            requestProducers.add(p5);
+
+            final HttpAsyncResponseConsumer<HttpResponse> c1 = new BasicAsyncResponseConsumer();
+            final HttpAsyncResponseConsumer<HttpResponse> c2 = new BasicAsyncResponseConsumer();
+            final HttpAsyncResponseConsumer<HttpResponse> c3 = new BasicAsyncResponseConsumer();
+            final HttpAsyncResponseConsumer<HttpResponse> c4 = new BasicAsyncResponseConsumer();
+            final HttpAsyncResponseConsumer<HttpResponse> c5 = new BasicAsyncResponseConsumer();
+            final List<HttpAsyncResponseConsumer<HttpResponse>> responseConsumers
= new ArrayList<HttpAsyncResponseConsumer<HttpResponse>>();
+            responseConsumers.add(c1);
+            responseConsumers.add(c2);
+            responseConsumers.add(c3);
+            responseConsumers.add(c4);
+            responseConsumers.add(c5);
+
+            final Future<List<HttpResponse>> future = this.client.executePipelined(target,
requestProducers, responseConsumers, null, null);
+            try {
+                future.get();
+            } catch (ExecutionException ex) {
+                final Throwable cause = ex.getCause();
+                Assert.assertTrue(cause instanceof ConnectionClosedException);
+            }
+
+            Assert.assertTrue(c1.isDone());
+            Assert.assertNotNull(c1.getResult());
+            Assert.assertTrue(c2.isDone());
+            Assert.assertNotNull(c2.getResult());
+            Assert.assertTrue(c2.isDone());
+            Assert.assertNotNull(c3.getResult());
+            Assert.assertTrue(c4.isDone());
+            Assert.assertNull(c4.getResult());
+            Assert.assertTrue(c5.isDone());
+            Assert.assertNull(c5.getResult());
+        }
+    }
+
 }



Mime
View raw message