-
Notifications
You must be signed in to change notification settings - Fork 18k
x/net/websocket: sockets served with http.ListenAndServeTLS have SSL handshake problems with most clients #11602
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
It actually turns out that this isn't an SSL problem at all. The same issue occurs if you just connect with Chrome and So websocket servers written in go are currently incompatible with most clients? I re-wrote the sample program to ignore TLS and Chrome still has a Forbidden 403: package main
import (
"golang.org/x/net/websocket"
"io"
"log"
"net/http"
)
func copyTest(ws *websocket.Conn) {
io.Copy(ws, ws)
}
func main() {
// setup http handler
http.Handle("/test", websocket.Handler(copyTest))
// start secure websocket server
log.Println("Listening for secure websocket connections on localhost port 8000...")
if err := http.ListenAndServe(":8000", nil); err != nil {
panic("ListenAndServe Error: " + err.Error())
}
} I also updated the client to not use SSL like so: var ws = new WebSocket("ws://localhost:8000/test"); |
Some more analysis: Here is a packet capture of the headers coming from Safari and Chrome. Remeber that the Safari request works, but Chrome does not. Perhaps the origin header can not be null? Safari:
Chrome:
|
Here are the headers that are different between the two: Safari:
Chrome:
|
For anyone else stuck on this... I have rewritten using github.com/gorilla/websocket and disabled the CheckOrigin function. This program works with Chrome and Safari. package main
import (
"github.com/gorilla/websocket"
"io"
"log"
"net/http"
)
// Specify options for gorilla websocket
var upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
CheckOrigin: func(r *http.Request) bool {
return true
},
}
// Create a handler function that calls an upgrade to websocket session using our upgrader parameters
func handler(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println(err)
return
}
for {
messageType, r, err := conn.NextReader()
if err != nil {
return
}
w, err := conn.NextWriter(messageType)
if err != nil {
//return err
}
if _, err := io.Copy(w, r); err != nil {
//return err
}
if err := w.Close(); err != nil {
//return err
}
}
}
func main() {
http.HandleFunc("/", handler)
log.Printf("Listening for SECURE websocket connections on port 8000.")
log.Fatal(http.ListenAndServeTLS(":8000", "cert.pem", "cert.key", nil))
} |
Looks like it's #10102? |
I think it is. For now, I am using gorilla websockets which is working okay. However, Gorilla requires more wasteful readers and writers than the x/net/websocket package does (and a lot more confusing code). I would like to see this added so I can switch back! Thanks for reading. |
If the issue is with checking the origin, can't we do something like below in case of /x/net/wesocket?: //.... I didn't test the code but I think it's one way to write our own logic regarding how the handshake should behave. |
I originally posted this here but was asked to make a new issue.
Websockets served over ListenAndServeTLS in the example program below fail to initiate SSL connections on nearly every client I have tried. Regular non-TLS connections work fine, and websites served also seem to be working fine over TLS. This is occurring on go version 1.4.2 x64.
Safari (version 9.0) works just great, but Firefox (version 39.0) and Chrome do not (version 43 on OSX). It also appears that javax.websocket gets a 403.
I get this error in Chrome:
Nothing is produced at the go terminal, unless i hit it with javax.websocket - which produces this:
In Safari I get the expected result in the javascript console:
in Firefox I get a 403 similar to Chrome and the console shows this:
Here is some go code to serve TLS websockets. sub in your own cert.key and cert.pem files.
Here is a javascript client. Sub in the proper domain name for your cert instead of localhost and connect using it. Results will be written to the javascript console.
The text was updated successfully, but these errors were encountered: