Skip to content

ReactorNetty websocket issue for multiple clients with different protocols #25315

@croissong

Description

@croissong

Affects: Spring Framework >= v5.2.6


We've observed an issue, using spring-cloud-gateway, where websocket handshakes fail if different clients, with different websocket protocols, are connecting in succession:

  1. wsClientA connects without any (sub-)protocol -> success
  2. wsClientB connects with protocol v10.stomp -> success
  3. wsClientA connects without any protocol -> failure

The bug first appeared in spring-webflux v5.2.6, with the newly introduced ReactorNettyRequestUpgradeStrategy (#24959 -> 0520ee0, ping @rstoyanchev).
The global WebsocketServerSpec.Builder is mutated for each request, persisting the client-specific protocol across requests, and thereby potentially breaking subsequent requests for clients with different (or null) subprotocols (see ReactorNettyRequestUpgradeStrategy.java#L89).
In the example above, the third handshake request is silently aborted in HttpServerOperations.java#L649, because websocketServerSpec.protocols() is set (by the second request), but ops.selectedSubprotocol() is null.

I created a simple WebSocketIntegration testcase to reproduce the issue:
https://github.com/Croissong/spring-framework/blob/ReactorNetty-websocket-protocol-bug/spring-webflux/src/test/java/org/springframework/web/reactive/socket/ReactorNettyWebsocketProtocolBugTests.java.
The test fails for all combinations using the ReactorHttpServer. However, the ReactorNettyWebSocketClient uses the same logic: ReactorNettyWebSocketClient.java#L111.

Metadata

Metadata

Assignees

Labels

in: webIssues in web modules (web, webmvc, webflux, websocket)type: regressionA bug that is also a regression

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions