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 2016/12/18 12:56:37 UTC

svn commit: r1774884 - /httpcomponents/httpcore/trunk/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/AbstractHttp1StreamDuplexer.java

Author: olegk
Date: Sun Dec 18 12:56:37 2016
New Revision: 1774884

URL: http://svn.apache.org/viewvc?rev=1774884&view=rev
Log:
Fixed infinite loop in HTTP/1.1 stream duplexer caused by a incomplete message fragment stuck in the session input buffer

Modified:
    httpcomponents/httpcore/trunk/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/AbstractHttp1StreamDuplexer.java

Modified: httpcomponents/httpcore/trunk/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/AbstractHttp1StreamDuplexer.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/AbstractHttp1StreamDuplexer.java?rev=1774884&r1=1774883&r2=1774884&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/AbstractHttp1StreamDuplexer.java (original)
+++ httpcomponents/httpcore/trunk/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/AbstractHttp1StreamDuplexer.java Sun Dec 18 12:56:37 2016
@@ -203,7 +203,9 @@ abstract class AbstractHttp1StreamDuplex
     }
 
     public final void onInput() throws HttpException, IOException {
-        do {
+        while (connState.compareTo(ConnectionState.SHUTDOWN) < 0) {
+            int totalBytesRead = 0;
+            int messagesReceived = 0;
             if (incomingMessage == null) {
 
                 if (connState.compareTo(ConnectionState.GRACEFUL_SHUTDOWN) >= 0 && inputIdle()) {
@@ -215,10 +217,12 @@ abstract class AbstractHttp1StreamDuplex
                 do {
                     bytesRead = inbuf.fill(ioSession.channel());
                     if (bytesRead > 0) {
+                        totalBytesRead += bytesRead;
                         inTransportMetrics.incrementBytesTransferred(bytesRead);
                     }
                     final IncomingMessage messageHead = incomingMessageParser.parse(inbuf, bytesRead == -1);
                     if (messageHead != null) {
+                        messagesReceived++;
                         incomingMessageParser.reset();
 
                         this.version = messageHead.getVersion();
@@ -249,16 +253,19 @@ abstract class AbstractHttp1StreamDuplex
             if (incomingMessage != null) {
                 final ContentDecoder contentDecoder = incomingMessage.getBody();
                 final int bytesRead = consumeData(contentDecoder);
+                if (bytesRead > 0) {
+                    totalBytesRead += bytesRead;
+                }
                 if (contentDecoder.isCompleted()) {
                     incomingMessage = null;
                     inputEnd();
                     ioSession.setEvent(SelectionKey.OP_READ);
                 }
-                if (bytesRead == 0) {
-                    break;
-                }
             }
-        } while (connState.compareTo(ConnectionState.SHUTDOWN) < 0 && inbuf.hasData());
+            if (totalBytesRead == 0 && messagesReceived == 0) {
+                break;
+            }
+        }
     }
 
     public final void onOutput() throws IOException, HttpException {