You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2021/07/15 20:58:39 UTC

[tomcat] branch main updated: Fix BZ 65448 for blocking IO

This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/main by this push:
     new 6a65741  Fix BZ 65448 for blocking IO
6a65741 is described below

commit 6a65741d13fce5cccf6824d2be8685394878b9a3
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Thu Jul 15 16:56:00 2021 +0100

    Fix BZ 65448 for blocking IO
    
    If the write completes (from the application perspective) but the
    encrypted data is not fully written, the connection (from the client's
    perspective) will appear to hang until the client sends another request
    (pipelining) or the connection times out.
---
 java/org/apache/tomcat/util/net/NioEndpoint.java      | 8 ++++++--
 java/org/apache/tomcat/util/net/SecureNioChannel.java | 5 +++++
 webapps/docs/changelog.xml                            | 6 ++++++
 3 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/java/org/apache/tomcat/util/net/NioEndpoint.java b/java/org/apache/tomcat/util/net/NioEndpoint.java
index ffdecc2..7865d42 100644
--- a/java/org/apache/tomcat/util/net/NioEndpoint.java
+++ b/java/org/apache/tomcat/util/net/NioEndpoint.java
@@ -1339,7 +1339,11 @@ public class NioEndpoint extends AbstractJsseEndpoint<NioChannel,SocketChannel>
                     n = getSocket().write(buffer);
                     if (n == -1) {
                         throw new EOFException();
-                    } else if (n == 0) {
+                    } else if (n == 0 && (buffer.hasRemaining() || getSocket().getOutboundRemaining() > 0)) {
+                        // n == 0 could be an incomplete write but it could also
+                        // indicate that a previous incomplete write of the
+                        // outbound buffer (for TLS) has now completed. Only
+                        // block if there is still data to write.
                         writeBlocking = true;
                         registerWriteInterest();
                         synchronized (writeLock) {
@@ -1362,7 +1366,7 @@ public class NioEndpoint extends AbstractJsseEndpoint<NioChannel,SocketChannel>
                         timeout = getWriteTimeout();
                         startNanos = 0;
                     }
-                } while (buffer.hasRemaining());
+                } while (buffer.hasRemaining() || getSocket().getOutboundRemaining() > 0);
             } else {
                 do {
                     n = getSocket().write(buffer);
diff --git a/java/org/apache/tomcat/util/net/SecureNioChannel.java b/java/org/apache/tomcat/util/net/SecureNioChannel.java
index 63af010..22e339f 100644
--- a/java/org/apache/tomcat/util/net/SecureNioChannel.java
+++ b/java/org/apache/tomcat/util/net/SecureNioChannel.java
@@ -801,6 +801,11 @@ public class SecureNioChannel extends NioChannel {
                 return 0;
             }
 
+            if (!src.hasRemaining()) {
+                // Nothing left to write
+                return 0;
+            }
+
             // The data buffer is empty, we can reuse the entire buffer.
             netOutBuffer.clear();
 
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 4cec1f7..3838cf3 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -140,6 +140,12 @@
         connection that were trying to write when this happened would time out.
         (markt)
       </fix>
+      <fix>
+        <bug>65448</bug>: When using TLS with NIO, it was possible for a
+        blocking response write to hang just before the final TLS packet
+        associated with the response until the connection timed out at which
+        point the final packet would be sent and the connection closed. (markt)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Jasper">

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org