product-apim icon indicating copy to clipboard operation
product-apim copied to clipboard

Stomp Websockets not working using Chrome

Open ecostanzi opened this issue 4 years ago • 4 comments

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:

ecostanzi avatar Mar 20 '20 16:03 ecostanzi

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

bhathiya avatar Mar 20 '20 16:03 bhathiya

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?

ecostanzi avatar Apr 07 '20 09:04 ecostanzi

No we haven't done this yet. You can do a custom implementation and plug until we have it in the product someday.

bhathiya avatar Apr 07 '20 17:04 bhathiya

Any solution to share please ?

Piscenois avatar May 25 '22 12:05 Piscenois