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/23 12:29:51 UTC

svn commit: r1437352 - in /httpcomponents/httpcore/trunk: ./ httpcore-nio/src/main/java/org/apache/http/nio/protocol/ httpcore-nio/src/main/java/org/apache/http/nio/reactor/ssl/

Author: olegk
Date: Wed Jan 23 11:29:51 2013
New Revision: 1437352

URL: http://svn.apache.org/viewvc?rev=1437352&view=rev
Log:
HTTPCORE-319: Non-blocking SSLIOSession can fail to shut down correctly when the underlying connection gets terminated abnormally by the opposite endpoint in case there is a truncated or corrupted encrypted content in the input buffer and there is still data in the output buffer that needs to be flushed out (most likely to occur with POST or PUT requests)

Modified:
    httpcomponents/httpcore/trunk/RELEASE_NOTES.txt
    httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestExecutor.java
    httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncService.java
    httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/reactor/ssl/SSLIOSession.java

Modified: httpcomponents/httpcore/trunk/RELEASE_NOTES.txt
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/RELEASE_NOTES.txt?rev=1437352&r1=1437351&r2=1437352&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/RELEASE_NOTES.txt (original)
+++ httpcomponents/httpcore/trunk/RELEASE_NOTES.txt Wed Jan 23 11:29:51 2013
@@ -10,6 +10,11 @@ Changes since 4.3-ALPHA1 
 * [HTTPCORE-323] Undocumented UnsupportedCharsetException in ContentType#getOrDefault.
   Contributed by Gary D. Gregory <ggregory at apache.org>
 
+* [HTTPCORE-319] Non-blocking SSLIOSession can fail to shut down correctly when the underlying
+  connection gets terminated abnormally by the opposite endpoint in case there is a truncated or
+  corrupted encrypted content in the input buffer and there is still data in the output buffer
+  that needs to be flushed out (most likely to occur with POST or PUT requests).
+  Contributed by Oleg Kalnichevski <olegk at apache.org>
 
 
 Release 4.3-ALPHA1 

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=1437352&r1=1437351&r2=1437352&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 Wed Jan 23 11:29:51 2013
@@ -263,6 +263,13 @@ public class HttpAsyncRequestExecutor im
                 closeHandler(getHandler(conn), new ConnectionClosedException("Connection closed"));
             }
         }
+        // Closing connection in an orderly manner and
+        // waiting for output buffer to get flushed.
+        // Do not want to wait indefinitely, though, in case
+        // the opposite end is not reading
+        if (conn.getSocketTimeout() <= 0) {
+            conn.setSocketTimeout(1000);
+        }
         conn.close();
     }
 

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=1437352&r1=1437351&r2=1437352&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 Wed Jan 23 11:29:51 2013
@@ -390,6 +390,13 @@ public class HttpAsyncService implements
     }
 
     public void endOfInput(final NHttpServerConnection conn) throws IOException {
+        // Closing connection in an orderly manner and
+        // waiting for output buffer to get flushed.
+        // Do not want to wait indefinitely, though, in case
+        // the opposite end is not reading
+        if (conn.getSocketTimeout() <= 0) {
+            conn.setSocketTimeout(1000);
+        }
         conn.close();
     }
 

Modified: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/reactor/ssl/SSLIOSession.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/reactor/ssl/SSLIOSession.java?rev=1437352&r1=1437351&r2=1437352&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/reactor/ssl/SSLIOSession.java (original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/reactor/ssl/SSLIOSession.java Wed Jan 23 11:29:51 2013
@@ -307,7 +307,7 @@ public class SSLIOSession implements IOS
             newMask = EventMask.READ_WRITE;
             break;
         case NEED_UNWRAP:
-            newMask = EventMask.READ;
+            newMask = EventMask.READ | (this.appEventMask & EventMask.WRITE);
             break;
         case NOT_HANDSHAKING:
             newMask = this.appEventMask;
@@ -357,6 +357,9 @@ public class SSLIOSession implements IOS
             if (result.getHandshakeStatus() != HandshakeStatus.NOT_HANDSHAKING) {
                 break;
             }
+            if (this.endOfStream) {
+                break;
+            }
         }
         return decrypted;
     }
@@ -562,6 +565,15 @@ public class SSLIOSession implements IOS
         this.session.setAttribute(name, obj);
     }
 
+    private static void formatOps(final StringBuilder buffer, int ops) {
+        if ((ops & SelectionKey.OP_READ) > 0) {
+            buffer.append('r');
+        }
+        if ((ops & SelectionKey.OP_WRITE) > 0) {
+            buffer.append('w');
+        }
+    }
+
     @Override
     public String toString() {
         final StringBuilder buffer = new StringBuilder();
@@ -579,7 +591,15 @@ public class SSLIOSession implements IOS
             break;
         }
         buffer.append("][");
+        formatOps(buffer, this.appEventMask);
+        buffer.append("][");
         buffer.append(this.sslEngine.getHandshakeStatus());
+        if (this.sslEngine.isInboundDone()) {
+            buffer.append("][inbound done][");
+        }
+        if (this.sslEngine.isOutboundDone()) {
+            buffer.append("][outbound done][");
+        }
         if (this.endOfStream) {
             buffer.append("][EOF][");
         }