記錄一個 Websocket 細節中的魔鬼 ~ Origin

基本上,用 Golang 來實作 Restful API 或是 Websocket Server 是非常好上手的,不過就在我們開開心心地做好一個 Echo Server ,開始拿工具測試時,奇怪的狀況發生了 …… 我們的 Lua Client 連不到 …… 為了釐清問題,開始換了幾種 Client 來測試,發覺 Python 的就可以成功連線,可是 wscat 就不行 ……

拜了谷歌大神之後,發現了下面這篇文

換成文中所示範的方式,基本上就可以了…….(如下)

$ wscat -c ws://localhsot:12345/echo -o localhost:12345

附記:一定要用 localhost 才可以,用 127.0.0.1 不行,我試著用遠端主機連線,直接用 IP 也不行,可是修改 /etc/hosts 替 IP 隨便編個名字就然後用名字就可以用 wscat 連線 ……. ( 有點好奇裡面的機制 )

wscat 中的 -o 是為 HTTP Header 中的 Origin 欄位,而這竟然會影響 Websocket 連線?

有了方向之後就摸出個所以然來了,以下出自 https://godoc.org/golang.org/x/net/websocket#Handler

Handler is a simple interface to a WebSocket browser client. It checks if Origin header is valid URL by default. You might want to verify websocket.Conn.Config().Origin in the func. If you use Server instead of Handler, you could call websocket.Origin and check the origin in your Handshake func. So, if you want to accept non-browser clients, which do not send an Origin header, set a Server.Handshake that does not check the origin.

當然我們可以嘗試把 Websocket Client 都加上 Origin ,不過萬一我們不能這麼做呢?StackOverFlow 上的善心人士提供了一個讓 Golang Websocket Server 繞過 Origin Check 的寫法

http.HandleFunc("/echo",
func (w http.ResponseWriter, req *http.Request) {
s := websocket.Server{Handler: websocket.Handler(webHandler)}
s.ServeHTTP(w, req)
});

來源 :http://stackoverflow.com/questions/19708330/serving-a-websocket-in-go

朝 Websocket 達人的領域又邁進了一小步

Show your support

Clapping shows how much you appreciated Devopstaku’s story.