spring-cloud / spring-cloud-gateway

An API Gateway built on Spring Framework and Spring Boot providing routing and more.
http://cloud.spring.io
Apache License 2.0
4.52k stars 3.32k forks source link

Sec-WebSocket-Extensions header is not passed to proxied server #1321

Open amizurov opened 5 years ago

amizurov commented 5 years ago

Expected behavior: proxied server should receive the Sec-WebSocket-Extensions header.

Current behavior: Configure gateway route for handling websocket connection. Client send request ->

        GET /ws HTTP/1.1
        Host: localhost:7788
        Upgrade: websocket
        Connection: Upgrade
        Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
        Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
        Sec-WebSocket-Version: 13

Proxied server not received Sec-WebSocket-Extensions header. This is header was filtered in WebsocketRoutingFilter.class.

Spring Cloud Gateway Version: 2.1.2.RELEASE

ryanjbaxter commented 5 years ago

This was done on purpose.

https://github.com/spring-cloud/spring-cloud-gateway/issues/143 cc: @spencergibb

amizurov commented 5 years ago

Hi, @ryanjbaxter and thanks for responding. I agree that WebSocket is a hop‑by‑hop protocol (Connection and Upgrade headers), but when a gateway received Upgrade request from a client it need to sent its own Upgrade request to a proxied server including the appropriate headers one of them is Sec-WebSocket-Extensions header. It is used in the WebSocket opening handshake to agree on a set of protocol-level extensions to use for the duration of the connection.

amizurov commented 5 years ago

@ryanjbaxter @spencergibb guys any update about issue ?

divyaJainPhilips commented 4 years ago

@amizurov did you find a solution to this problem. Facing the same issue while establishing websocket connection

amizurov commented 4 years ago

@amizurov did you find a solution to this problem. Facing the same issue while establishing websocket connection

Yes, we patched gateway and will prepare pull request a soon as possible.

divyaJainPhilips commented 4 years ago

@amizurov any idea on the timeline when u will be able to create a pull request

amizurov commented 4 years ago

@divyaJainPhilips Hi, sorry for a long time response.I thought it would be enough to forward Sec-WebSocket-Extensions header to downstream server but i was wrong. The gateway do proxy stuff in 2 steps: 1) establish websocket connection with origin client (according client upgrade request) 2) then establish connection to proxied server (without sec-websocket origin client headers)

So that is mean even i skip filter for sec-websocket-extensions header and proxied server accept them the origin client already received (101) response without this extensions.

@spencergibb, @ryanjbaxter, @violetagg WDYT ? I was sure that the origin client doesn't receive a response until the proxied server answers it, also i'm wonder why WebsocketServerOperations set WebSocketServerCompressionHandler only if SimpleCompressionHandler present in pipeline.

ryanjbaxter commented 4 years ago

To tell you the truth I am not sure without digging into this some more. IDK if @spencergibb has any ideas

amizurov commented 4 years ago

Guys i understand that you are very busy, but for solving this issue i need some feedback to do all stuff right. Because i see that a lot of components reactor-netty, spring-webflux related with this problem.

leinadpb commented 4 years ago

Any solution so far?

amizurov commented 4 years ago

@leinadpb Hi In our project, we made a patch for this.

spencergibb commented 4 years ago

@amizurov mind sharing your patch here or submit a PR?

amizurov commented 4 years ago

@spencergibb hi of course, i'll try to do it as soon as time appears due to the current situation, we love OSS and happy to contribute, maybe @Fetsivalen can do it faster.

Fetsivalen commented 4 years ago

Hi @amizurov @spencergibb , Currently, I'm s bit overwhelmed with other activities. The change I planned to propose and contribute was not just about the headers but about changing the way Spring Cloud Gateway works with web-socket handshake requests.

Right now Gateway establishes ws connection with the client and in fallback establish ws connection with the backend service, which is wrong in my case and I inverted this behavior which gives me the ability to provide to the client response from the backend service.

There are a few other minor stuff I did as well, but firstly I'd like to get the feedback from @spencergibb is such behavior welcomed, and, maybe, it should be contributed in the scope of another GitHub ticket.

In any case, there are a few dependencies I plan to start with, and only after it works on this one:

https://github.com/spring-projects/spring-framework/issues/25119 (can be patched client manually, but still it should be done in spring-boot, not here ) https://github.com/reactor/reactor-netty/issues/1091 (hope I will dig into it soon) https://github.com/netty/netty/issues/10277 (String still can be parsed, but I'm not sure is this "solution" will be welcomed here) other ones seem already implemented.

qradimir commented 2 years ago

Any ETA on this issue?