I am trying to connect to websocket route running in Go. I think I don't need to share server details, see the following Postman output:
Connected to 0.0.0.0:1323/ws/earthquakes/stream
Handshake Details
Request URL: http://0.0.0.0:1323/ws/earthquakes/stream
Request Method: GET
Status Code: 101 Switching Protocols
Request Headers
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: xxx
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Host: 0.0.0.0:1323
Response Headers
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: xxx
Postman successfully connects and I can get messages with zero config. No protocol specified, no config, literally nothing. When I try to do the same thing with Javascript with only this line of code (again no config):
const ws = new WebSocket(wsURL + "earthquakes/stream", "echo-protocol");
I get:
GET
ws://0.0.0.0:1323/ws/earthquakes/stream
13:06:32.776 Firefox ws://0.0.0.0:1323/ws/earthquakes/stream sunucusuyla bağlantı kuramıyor.
meaning Firefox cannot establish connection with the server.
I changed wsURL from ws://0.0.0.0:1323/ws/
to http://0.0.0.0:1323/ws/
to match the Postman's URL, but nope, JS autocorrects the http to ws.
There is no "you are hosting the Vue from container and container serves the page in your browser so you cannot connect to backend" thing too. If I can connect to this websocket with Postman, there is no network isolation between the backend and the host. What is wrong?
Edit:
Extra details on the self answer, Frontend and Backend was connected with a Docker network, but the browser used in testing was not connected to this Docker network. So hosts are different even if you host the frontend on your Docker container. This is why AllowedOrigin was needed.
Turns out that CheckOrigin
is not needed for websocket requests coming from Postman, but it is strictly required and needed for Javascript. I don't know why, or how this happens, but
var (
upgrader = websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool {
return true
},
}
)
allowing all origins for testing worked. Should be same solution (see this link for understanding the CheckOrigin and applying to other languages) for all websocket servers. Worked in Gorilla WS in GoLang at least.
A disclaimer:
Please do not use this in production code. This setup will allow front-ends hosted anywhere to send requests to your back-end, which can lead to security issues.