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 3d5cd321b7 Fix BZ-66508 - avoid delay on close after write error with 
NIO2
3d5cd321b7 is described below

commit 3d5cd321b7a41ca4a3da8c20a80737021779d742
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Wed Mar 8 18:23:05 2023 +0000

    Fix BZ-66508 - avoid delay on close after write error with NIO2
    
    https://bz.apache.org/bugzilla/show_bug.cgi?id=66508
---
 .../websocket/server/WsHttpUpgradeHandler.java     | 22 +++++++++++++++++-----
 .../server/WsRemoteEndpointImplServer.java         |  2 +-
 webapps/docs/changelog.xml                         |  9 +++++++++
 3 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/java/org/apache/tomcat/websocket/server/WsHttpUpgradeHandler.java 
b/java/org/apache/tomcat/websocket/server/WsHttpUpgradeHandler.java
index b49858ccdc..7660c48cdf 100644
--- a/java/org/apache/tomcat/websocket/server/WsHttpUpgradeHandler.java
+++ b/java/org/apache/tomcat/websocket/server/WsHttpUpgradeHandler.java
@@ -16,6 +16,7 @@
  */
 package org.apache.tomcat.websocket.server;
 
+import java.io.EOFException;
 import java.io.IOException;
 import java.util.List;
 import java.util.Map;
@@ -241,11 +242,22 @@ public class WsHttpUpgradeHandler implements 
InternalHttpUpgradeHandler {
     private void close(CloseReason cr) {
         /*
          * Any call to this method is a result of a problem reading from the
-         * client. At this point that state of the connection is unknown.
-         * Attempt to send a close frame to the client and then close the 
socket
-         * immediately. There is no point in waiting for a close frame from the
-         * client because there is no guarantee that we can recover from
-         * whatever messed up state the client put the connection into.
+         * client. At this point that state of the connection is unknown. First
+         * attempt to clear the handler for any in-flight message write (that
+         * probably failed). If using NIO2 is is possible that the original
+         * error occurred on a write but this method was called during a read.
+         * The in-progress write will block the sending of the close frame
+         * unless the handler is cleared (effectively signalling the write
+         * failed).
+         */
+        wsRemoteEndpointServer.clearHandler(new EOFException(), true);
+
+        /* Then:
+         *  - send a close frame to the client
+         * - close the socket immediately.
+         * There is no point in waiting for a close frame from the client
+         * because there is no guarantee that we can recover from whatever
+         * messed up state the client put the connection into.
          */
         wsSession.onClose(cr);
     }
diff --git 
a/java/org/apache/tomcat/websocket/server/WsRemoteEndpointImplServer.java 
b/java/org/apache/tomcat/websocket/server/WsRemoteEndpointImplServer.java
index 1b5ac740f1..28d591f65d 100644
--- a/java/org/apache/tomcat/websocket/server/WsRemoteEndpointImplServer.java
+++ b/java/org/apache/tomcat/websocket/server/WsRemoteEndpointImplServer.java
@@ -268,7 +268,7 @@ public class WsRemoteEndpointImplServer extends 
WsRemoteEndpointImplBase {
      *                      requirements of
      *                      {@link javax.websocket.RemoteEndpoint.Async}
      */
-    private void clearHandler(Throwable t, boolean useDispatch) {
+    void clearHandler(Throwable t, boolean useDispatch) {
         // Setting the result marks this (partial) message as
         // complete which means the next one may be sent which
         // could update the value of the handler. Therefore, keep a
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 9c775e9f3d..42e5dec4db 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -136,6 +136,15 @@
       </fix>
     </changelog>
   </subsection>
+  <subsection name="WebSocket">
+    <changelog>
+      <fix>
+        <bug>66508</bug>: When using WebSocket with NIO2, avoid waiting for
+        a timeout before sending the close frame if an I/O error occurs during 
a
+        write. (markt)
+      </fix>
+    </changelog>
+  </subsection>
   <subsection name="Other">
     <changelog>
       <add>


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

Reply via email to