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
commit 5a60314251f211d73937fb9ce0f6a391f4ab3d11 Author: Mark Thomas <ma...@apache.org> AuthorDate: Mon Jun 23 11:55:56 2025 +0100 Always call Configurator.afterResponse() regardless of success/failure --- java/org/apache/tomcat/websocket/WsWebSocketContainer.java | 7 +++++-- webapps/docs/changelog.xml | 6 ++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/java/org/apache/tomcat/websocket/WsWebSocketContainer.java b/java/org/apache/tomcat/websocket/WsWebSocketContainer.java index 3390c8dc1d..faef999e71 100644 --- a/java/org/apache/tomcat/websocket/WsWebSocketContainer.java +++ b/java/org/apache/tomcat/websocket/WsWebSocketContainer.java @@ -80,6 +80,8 @@ public class WsWebSocketContainer implements WebSocketContainer, BackgroundProce private static final byte[] ROOT_URI_BYTES = "/".getBytes(StandardCharsets.ISO_8859_1); private static final byte[] HTTP_VERSION_BYTES = " HTTP/1.1\r\n".getBytes(StandardCharsets.ISO_8859_1); + private static final HandshakeResponse EMPTY_HANDSHAKE_RESPONSE = new WsHandshakeResponse(); + private volatile AsynchronousChannelGroup asynchronousChannelGroup = null; private final Object asynchronousChannelGroupLock = new Object(); @@ -275,6 +277,7 @@ public class WsWebSocketContainer implements WebSocketContainer, BackgroundProce Transformation transformation = null; AsyncChannelWrapper channel = null; + HandshakeResponse handshakeResponse = EMPTY_HANDSHAKE_RESPONSE; try { // Open the connection Future<Void> fConnect = socketChannel.connect(sa); @@ -375,8 +378,7 @@ public class WsWebSocketContainer implements WebSocketContainer, BackgroundProce sm.getString("wsWebSocketContainer.invalidStatus", Integer.toString(httpResponse.status))); } } - HandshakeResponse handshakeResponse = httpResponse.handshakeResponse(); - clientEndpointConfiguration.getConfigurator().afterResponse(handshakeResponse); + handshakeResponse = httpResponse.handshakeResponse(); // Sub-protocol List<String> protocolHeaders = handshakeResponse.getHeaders().get(Constants.WS_PROTOCOL_HEADER_NAME); @@ -419,6 +421,7 @@ public class WsWebSocketContainer implements WebSocketContainer, BackgroundProce | URISyntaxException | AuthenticationException e) { throw new DeploymentException(sm.getString("wsWebSocketContainer.httpRequestFailed", path), e); } finally { + clientEndpointConfiguration.getConfigurator().afterResponse(handshakeResponse); if (!success) { if (channel != null) { channel.close(); diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index 770acaaacc..45d060ff3c 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -263,6 +263,12 @@ <code>getUserX509CertificateChain()</code> that provides the client certificate chain, if present, during the WebSocket handshake. (markt) </add> + <fix> + Implement the clarification in WebSocket 2.3 that the method + <code>ClientEndpointConfig.Configurator.afterResponse()</code> must be + called after every WebSocket handshake regardless of whether the + handshake is successful or not. (markt) + </fix> <!-- Entries for backport and removal before 12.0.0-M1 below this line --> </changelog> </subsection> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org