product-apim
product-apim copied to clipboard
Stomp Websockets not working using Chrome
Description
I'm creating a js app that connects to a spring app via websocket and stomp. This app always work when connecting directly to the websocket, but fails on Chrome when using the API gateway.
When connecting directly to the service it always works
stompClient = Stomp.client("ws://my-spring-service:8080/gs-guide-websocket");
When connecting to the service via API Manager does NOT work on chrome:
stompClient = Stomp.client("ws://my-wso2-instance:9099/wsocket/1.0.0?access_token=<my-token>");
The error is
Error during WebSocket handshake: Sent non-empty 'Sec-WebSocket-Protocol' header but no response was received
.
Motivation
The request contains the websocket subprotocols in the Sec-Websocket-Protocol
:
...
Sec-WebSocket-Protocol: v10.stomp, v11.stomp
Sec-WebSocket-Extensions: permessage-deflate
Sec-WebSocket-Key: JNW2u5tJX3d5d6kWQHiQ2g==
...
The response returned by the service (contains the Sec-Websocket-Protocol
):
Connection: upgrade
Date: Fri, 20 Mar 2020 15:36:01 GMT
Sec-WebSocket-Accept: np1xwDgzcT5lHkoVIgQJnzoNij4=
Sec-WebSocket-Extensions: permessage-deflate;client_max_window_bits=15
Sec-WebSocket-Protocol: v10.stomp
Upgrade: websocket
The response returne by the API Manager (does NOT contain the Sec-Websocket-Protocol
header:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: VhC2uL0J5JFu9wd7xtFSmp1fNck=
The above response is not accepted by chrome, chrome needs the Sec-WebSocket-Protocol
in the response.
According to this website: https://whatpr.org/html/4105/web-sockets.html "The connection will only be established if the server reports that it has selected one of these subprotocols"
Steps to reproduce:
- Deploy this app behind the APIM https://github.com/spring-guides/gs-messaging-stomp-websocket/tree/master/complete
- Create a new Websocket API in the API manager and set the endpoint to
ws://the-spring-app:8080/gs-guide-websocket
- run these static files on localhost and change this line to
stompClient = Stomp.client("ws://my-spring-service:8080/gs-guide-websocket");
-> It works because the spring app returns all the haders - change the endpoint and point to the api gateway
stompClient = Stomp.client("ws://my-wso2-instance:9099/wsocket/1.0.0?access_token=<my-token>");
--> it does NOT work due to the missing header
Affected Product Version:
WSO2 API-M v3.1.0 Beta
Environment details (with versions):
- OS: Windows 10
- Client: Chrome, Firefox
- Env (Docker/K8s): Linux Installer on VM
Optional Fields
Related Issues:
Suggested Labels:
Suggested Assignees:
We should be able to implement a custom subprotocol handler and provide it in the ws.subprotocol.handler.class(comma separated) parameter in websocket inbound configuration which will handle the custom subprotocol. A sample handler can be found in [1].
[1] - https://github.com/wso2/carbon-mediation/blob/master/components/inbound-endpoints/org.wso2.carbon.inbound.endpoint/src/main/java/org/wso2/carbon/inbound/endpoint/protocol/websocket/subprotocols/EchoSubprotocolHandler.java
from @sameeragunarathne
Thanks @bhathiya, is it something we can configure on our instance of carbon or has it to be fixed in the source code of carbon?
No we haven't done this yet. You can do a custom implementation and plug until we have it in the product someday.
Any solution to share please ?