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