-
Notifications
You must be signed in to change notification settings - Fork 38.8k
Description
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:
- wsClientA connects without any (sub-)protocol -> success
- wsClientB connects with protocol
v10.stomp-> success - 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.