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 2015/06/05 11:18:01 UTC

svn commit: r1683685 - in /httpcomponents/httpclient/trunk/httpclient/src: main/java/org/apache/http/conn/ main/java/org/apache/http/impl/execchain/ test/java/org/apache/http/impl/execchain/

Author: olegk
Date: Fri Jun  5 09:18:00 2015
New Revision: 1683685

URL: http://svn.apache.org/r1683685
Log:
HTTPCLIENT-1655: HttpClient sends RST instead of FIN ACK sequence when using non-persistant connections

Modified:
    httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/conn/ConnectionReleaseTrigger.java
    httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/execchain/ConnectionHolder.java
    httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/execchain/HttpResponseProxy.java
    httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/execchain/ResponseEntityProxy.java
    httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/execchain/TestMainClientExec.java
    httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/execchain/TestMinimalClientExec.java
    httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/execchain/TestResponseEntityWrapper.java

Modified: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/conn/ConnectionReleaseTrigger.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/conn/ConnectionReleaseTrigger.java?rev=1683685&r1=1683684&r2=1683685&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/conn/ConnectionReleaseTrigger.java (original)
+++ httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/conn/ConnectionReleaseTrigger.java Fri Jun  5 09:18:00 2015
@@ -31,8 +31,7 @@ import java.io.IOException;
 /**
  * Interface for releasing a connection. This can be implemented by various
  * "trigger" objects which are associated with a connection, for example
- * a {@link EofSensorInputStream stream} or an {@link BasicManagedEntity entity}
- * or the {@link ManagedClientConnection connection} itself.
+ * a {@link EofSensorInputStream} or the {@link ManagedHttpClientConnection} itself.
  * <p>
  * The methods in this interface can safely be called multiple times.
  * The first invocation releases the connection, subsequent calls

Modified: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/execchain/ConnectionHolder.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/execchain/ConnectionHolder.java?rev=1683685&r1=1683684&r2=1683685&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/execchain/ConnectionHolder.java (original)
+++ httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/execchain/ConnectionHolder.java Fri Jun  5 09:18:00 2015
@@ -30,6 +30,7 @@ package org.apache.http.impl.execchain;
 import java.io.Closeable;
 import java.io.IOException;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.apache.commons.logging.Log;
 import org.apache.http.HttpClientConnection;
@@ -50,13 +51,12 @@ class ConnectionHolder implements Connec
 
     private final HttpClientConnectionManager manager;
     private final HttpClientConnection managedConn;
+    private final AtomicBoolean released;
     private volatile boolean reusable;
     private volatile Object state;
     private volatile long validDuration;
     private volatile TimeUnit tunit;
 
-    private volatile boolean released;
-
     public ConnectionHolder(
             final Log log,
             final HttpClientConnectionManager manager,
@@ -65,6 +65,7 @@ class ConnectionHolder implements Connec
         this.log = log;
         this.manager = manager;
         this.managedConn = managedConn;
+        this.released = new AtomicBoolean(false);
     }
 
     public boolean isReusable() {
@@ -90,19 +91,40 @@ class ConnectionHolder implements Connec
         }
     }
 
+    private void releaseConnection(final boolean reusable) {
+        if (this.released.compareAndSet(false, true)) {
+            synchronized (this.managedConn) {
+                if (reusable) {
+                    this.manager.releaseConnection(this.managedConn,
+                            this.state, this.validDuration, this.tunit);
+                } else {
+                    try {
+                        this.managedConn.close();
+                        log.debug("Connection discarded");
+                    } catch (final IOException ex) {
+                        if (this.log.isDebugEnabled()) {
+                            this.log.debug(ex.getMessage(), ex);
+                        }
+                    } finally {
+                        this.manager.releaseConnection(
+                                this.managedConn, null, 0, TimeUnit.MILLISECONDS);
+                    }
+                }
+            }
+        }
+    }
+
     @Override
     public void releaseConnection() {
-        synchronized (this.managedConn) {
-            if (this.released) {
-                return;
-            }
-            this.released = true;
-            if (this.reusable) {
-                this.manager.releaseConnection(this.managedConn,
-                        this.state, this.validDuration, this.tunit);
-            } else {
+        releaseConnection(this.reusable);
+    }
+
+    @Override
+    public void abortConnection() {
+        if (this.released.compareAndSet(false, true)) {
+            synchronized (this.managedConn) {
                 try {
-                    this.managedConn.close();
+                    this.managedConn.shutdown();
                     log.debug("Connection discarded");
                 } catch (final IOException ex) {
                     if (this.log.isDebugEnabled()) {
@@ -117,41 +139,20 @@ class ConnectionHolder implements Connec
     }
 
     @Override
-    public void abortConnection() {
-        synchronized (this.managedConn) {
-            if (this.released) {
-                return;
-            }
-            this.released = true;
-            try {
-                this.managedConn.shutdown();
-                log.debug("Connection discarded");
-            } catch (final IOException ex) {
-                if (this.log.isDebugEnabled()) {
-                    this.log.debug(ex.getMessage(), ex);
-                }
-            } finally {
-                this.manager.releaseConnection(
-                        this.managedConn, null, 0, TimeUnit.MILLISECONDS);
-            }
-        }
-    }
-
-    @Override
     public boolean cancel() {
-        final boolean alreadyReleased = this.released;
+        final boolean alreadyReleased = this.released.get();
         log.debug("Cancelling request execution");
         abortConnection();
         return !alreadyReleased;
     }
 
     public boolean isReleased() {
-        return this.released;
+        return this.released.get();
     }
 
     @Override
     public void close() throws IOException {
-        abortConnection();
+        releaseConnection(false);
     }
 
 }

Modified: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/execchain/HttpResponseProxy.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/execchain/HttpResponseProxy.java?rev=1683685&r1=1683684&r2=1683685&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/execchain/HttpResponseProxy.java (original)
+++ httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/execchain/HttpResponseProxy.java Fri Jun  5 09:18:00 2015
@@ -61,7 +61,7 @@ class HttpResponseProxy implements Close
     @Override
     public void close() throws IOException {
         if (this.connHolder != null) {
-            this.connHolder.abortConnection();
+            this.connHolder.close();
         }
     }
 

Modified: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/execchain/ResponseEntityProxy.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/execchain/ResponseEntityProxy.java?rev=1683685&r1=1683684&r2=1683685&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/execchain/ResponseEntityProxy.java (original)
+++ httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/execchain/ResponseEntityProxy.java Fri Jun  5 09:18:00 2015
@@ -61,7 +61,13 @@ class ResponseEntityProxy extends HttpEn
         this.connHolder = connHolder;
     }
 
-    private void cleanup() {
+    private void cleanup() throws IOException {
+        if (this.connHolder != null) {
+            this.connHolder.close();
+        }
+    }
+
+    private void abortConnection() throws IOException {
         if (this.connHolder != null) {
             this.connHolder.abortConnection();
         }
@@ -69,13 +75,7 @@ class ResponseEntityProxy extends HttpEn
 
     public void releaseConnection() throws IOException {
         if (this.connHolder != null) {
-            try {
-                if (this.connHolder.isReusable()) {
-                    this.connHolder.releaseConnection();
-                }
-            } finally {
-                cleanup();
-            }
+            this.connHolder.releaseConnection();
         }
     }
 
@@ -100,6 +100,12 @@ class ResponseEntityProxy extends HttpEn
         try {
             this.wrappedEntity.writeTo(outstream);
             releaseConnection();
+        } catch (IOException ex) {
+            abortConnection();
+            throw ex;
+        } catch (RuntimeException ex) {
+            abortConnection();
+            throw ex;
         } finally {
             cleanup();
         }
@@ -112,6 +118,12 @@ class ResponseEntityProxy extends HttpEn
             // reading trailers after the response body:
             wrapped.close();
             releaseConnection();
+        } catch (IOException ex) {
+            abortConnection();
+            throw ex;
+        } catch (RuntimeException ex) {
+            abortConnection();
+            throw ex;
         } finally {
             cleanup();
         }
@@ -132,6 +144,12 @@ class ResponseEntityProxy extends HttpEn
                     throw ex;
                 }
             }
+        } catch (IOException ex) {
+            abortConnection();
+            throw ex;
+        } catch (RuntimeException ex) {
+            abortConnection();
+            throw ex;
         } finally {
             cleanup();
         }

Modified: httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/execchain/TestMainClientExec.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/execchain/TestMainClientExec.java?rev=1683685&r1=1683684&r2=1683685&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/execchain/TestMainClientExec.java (original)
+++ httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/execchain/TestMainClientExec.java Fri Jun  5 09:18:00 2015
@@ -305,7 +305,7 @@ public class TestMainClientExec {
 
         Mockito.verify(connManager, Mockito.times(1)).releaseConnection(
                 managedConn, null, 0, TimeUnit.MILLISECONDS);
-        Mockito.verify(managedConn, Mockito.times(1)).shutdown();
+        Mockito.verify(managedConn, Mockito.times(1)).close();
     }
 
     @Test

Modified: httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/execchain/TestMinimalClientExec.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/execchain/TestMinimalClientExec.java?rev=1683685&r1=1683684&r2=1683685&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/execchain/TestMinimalClientExec.java (original)
+++ httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/execchain/TestMinimalClientExec.java Fri Jun  5 09:18:00 2015
@@ -202,7 +202,7 @@ public class TestMinimalClientExec {
 
         Mockito.verify(connManager, Mockito.times(1)).releaseConnection(
                 managedConn, null, 0, TimeUnit.MILLISECONDS);
-        Mockito.verify(managedConn, Mockito.times(1)).shutdown();
+        Mockito.verify(managedConn, Mockito.times(1)).close();
     }
 
     @Test

Modified: httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/execchain/TestResponseEntityWrapper.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/execchain/TestResponseEntityWrapper.java?rev=1683685&r1=1683684&r2=1683685&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/execchain/TestResponseEntityWrapper.java (original)
+++ httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/execchain/TestResponseEntityWrapper.java Fri Jun  5 09:18:00 2015
@@ -85,7 +85,7 @@ public class TestResponseEntityWrapper {
         Mockito.when(connHolder.isReleased()).thenReturn(true);
         Mockito.doThrow(new SocketException()).when(instream).close();
         EntityUtils.consume(wrapper);
-        Mockito.verify(connHolder).abortConnection();
+        Mockito.verify(connHolder).close();
     }
 
     @Test