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

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


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

commit a17e9d9c0d59b8de86872997018cd47718129c46
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 42ddfcb..64cdfc6 100644
--- a/java/org/apache/tomcat/util/net/NioEndpoint.java
+++ b/java/org/apache/tomcat/util/net/NioEndpoint.java
@@ -1337,7 +1337,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) {
@@ -1360,7 +1364,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 d5debbc..3bc651f 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-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to