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 2013/01/29 15:35:11 UTC

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

Author: olegk
Date: Tue Jan 29 14:35:10 2013
New Revision: 1439909

URL: http://svn.apache.org/viewvc?rev=1439909&view=rev
Log:
HTTPASYNC-34: a proper fix for incorrect handling of prematurely termination of a persistent connection by the opposite end

Modified:
    httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BasicAsyncClientExchangeHandler.java
    httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncClientExchangeHandler.java
    httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestExecutor.java
    httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestBasicAsyncClientExchangeHandler.java
    httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestHttpAsyncRequestExecutor.java

Modified: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BasicAsyncClientExchangeHandler.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BasicAsyncClientExchangeHandler.java?rev=1439909&r1=1439908&r2=1439909&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BasicAsyncClientExchangeHandler.java (original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/BasicAsyncClientExchangeHandler.java Tue Jan 29 14:35:10 2013
@@ -30,6 +30,7 @@ package org.apache.http.nio.protocol;
 import java.io.IOException;
 import java.util.concurrent.Future;
 
+import org.apache.http.ConnectionClosedException;
 import org.apache.http.ConnectionReuseStrategy;
 import org.apache.http.HttpException;
 import org.apache.http.HttpRequest;
@@ -185,6 +186,10 @@ public class BasicAsyncClientExchangeHan
         return this.connReuseStrategy.keepAlive(response, this.localContext);
     }
 
+    public void inputTerminated() {
+        failed(new ConnectionClosedException("Connection closed"));
+    }
+
     public void failed(final Exception ex) {
         try {
             if (!this.requestSent) {

Modified: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncClientExchangeHandler.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncClientExchangeHandler.java?rev=1439909&r1=1439908&r2=1439909&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncClientExchangeHandler.java (original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncClientExchangeHandler.java Tue Jan 29 14:35:10 2013
@@ -139,6 +139,12 @@ public interface HttpAsyncClientExchange
     boolean keepAlive(HttpResponse response);
 
     /**
+     * Invoked to signal that the connection has been terminated prematurely
+     * by the opposite end.
+     */
+    void inputTerminated();
+
+    /**
      * Invoked to signal that the response processing terminated abnormally.
      *
      * @param ex exception

Modified: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestExecutor.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestExecutor.java?rev=1439909&r1=1439908&r2=1439909&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestExecutor.java (original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestExecutor.java Tue Jan 29 14:35:10 2013
@@ -244,8 +244,14 @@ public class HttpAsyncRequestExecutor im
         if (state != null) {
             if (state.getRequestState().compareTo(MessageState.READY) != 0) {
                 state.invalidate();
-                HttpAsyncClientExchangeHandler handler = getHandler(conn);
-                handler.failed(new ConnectionClosedException("Connection closed"));
+            }
+            HttpAsyncClientExchangeHandler handler = getHandler(conn);
+            if (handler != null) {
+                if (state.isValid()) {
+                    handler.inputTerminated();
+                } else {
+                    handler.failed(new ConnectionClosedException("Connection closed"));
+                }
             }
         }
         // Closing connection in an orderly manner and

Modified: httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestBasicAsyncClientExchangeHandler.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestBasicAsyncClientExchangeHandler.java?rev=1439909&r1=1439908&r2=1439909&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestBasicAsyncClientExchangeHandler.java (original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestBasicAsyncClientExchangeHandler.java Tue Jan 29 14:35:10 2013
@@ -29,6 +29,9 @@ package org.apache.http.nio.protocol;
 
 import java.util.concurrent.ExecutionException;
 
+import junit.framework.Assert;
+
+import org.apache.http.ConnectionClosedException;
 import org.apache.http.ConnectionReuseStrategy;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpVersion;
@@ -42,7 +45,6 @@ import org.apache.http.protocol.Executio
 import org.apache.http.protocol.HttpContext;
 import org.apache.http.protocol.HttpProcessor;
 import org.junit.After;
-import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mockito;
@@ -349,6 +351,17 @@ public class TestBasicAsyncClientExchang
     }
 
     @Test
+    public void testInputTerminated() throws Exception {
+        this.exchangeHandler.inputTerminated();
+        Mockito.verify(this.responseConsumer).failed(Mockito.<ConnectionClosedException>any());
+        try {
+            this.exchangeHandler.getFuture().get();
+            Assert.fail("ExecutionException expected");
+        } catch (final ExecutionException exex) {
+        }
+    }
+
+    @Test
     public void testIsDone() throws Exception {
         this.exchangeHandler.isDone();
         Mockito.verify(this.responseConsumer).isDone();

Modified: httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestHttpAsyncRequestExecutor.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestHttpAsyncRequestExecutor.java?rev=1439909&r1=1439908&r2=1439909&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestHttpAsyncRequestExecutor.java (original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestHttpAsyncRequestExecutor.java Tue Jan 29 14:35:10 2013
@@ -538,6 +538,20 @@ public class TestHttpAsyncRequestExecuto
     }
 
     @Test
+    public void testPrematureEndOfInputRequestReady() throws Exception {
+        final State state = new HttpAsyncRequestExecutor.State();
+        state.setRequestState(MessageState.READY);
+        this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
+        this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
+
+        this.protocolHandler.endOfInput(this.conn);
+
+        Assert.assertTrue(state.isValid());
+
+        Mockito.verify(this.exchangeHandler).inputTerminated();
+    }
+
+    @Test
     public void testTimeoutNoHandler() throws Exception {
         final State state = new HttpAsyncRequestExecutor.State();
         this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);