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:41:28 UTC

[tomcat] branch 9.0.x 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 9.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/9.0.x by this push:
     new 171a2cd  Fix BZ 65448 for blocking IO
171a2cd is described below

commit 171a2cdce037af67f67f474f48848ba19c9b8766
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 d4559bc..0f73308 100644
--- a/java/org/apache/tomcat/util/net/NioEndpoint.java
+++ b/java/org/apache/tomcat/util/net/NioEndpoint.java
@@ -1364,7 +1364,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) {
@@ -1387,7 +1391,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 8e28ef8..3a234be 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="Web applications">

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