spring-cloud / spring-cloud/spring-cloud-gateway
Server WebSocket handshake errors should result in handshake error returned to client
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 4.9k
- Forks
- 3.5k
- Avg merge
- 20h 57m
- Merged PRs (30d)
- 8
Description
- As a spring cloud gateway user
- in order to route traffic to websocket servers that perform authentication at the websocket handshake time (which is a valid behavior according to WSS specs section-4.2.2 ) and return a 401 status code to clients
- I need to be able handle server WS handshake failure and to return the original (e.g. 401) status to websocket client handshake
Currently, as previously reported in #857 (which was marked as a duplicate for #845), the gateway is first returning the WSS handshake response (HTTP/1.1 101 Switching Protocols triggered in ReactorNettyRequestUpgradeStrategy) prior to contacting the server and receiving the 401 status, and finally returns a default Server internal error to the client
Traces and steps to reproduce are detailed into https://stackoverflow.com/questions/63196638/spring-cloud-gateway-hides-server-websocket-handshake-401-failures-to-clients
I'm suspecting the following dependencies are necessary to fix this issue:
- client code (Netty client?) needs to expose the observed HTTP response code during handshake. Currently, the exception does not provide access to the status code programmatically (it is only present in the exception message).
io.netty.handler.codec.http.websocketx.WebSocketHandshakeException: Invalid handshake response getStatus: 401 Unauthorized
at io.netty.handler.codec.http.websocketx.WebSocketClientHandshaker13.verify(WebSocketClientHandshaker13.java:274) ~[netty-codec-http-4.1.51.Final.jar:4.1.51.Final]
- gateway client code (at WebsocketRoutingFilter) needs to extract the client handshake error and flow it up properly to the server code code.
- server code (ReactorNettyRequestUpgradeStrategy in spring-webflux) needs to receive and collect server errors during client handshake and return them to the client prior to committing the websocket handshake
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Read WebsocketRoutingFilter and ReactorNettyRequestUpgradeStrategy first, then trace the Netty WebSocketHandshakeException path described in the issue. Reproduce the 401 handshake case using the linked steps. Done means the original server handshake status reaches the WebSocket client instead of 101 followed by a generic internal error.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, spring, spring-boot
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100