Skip to content
This repository has been archived by the owner on Jan 27, 2021. It is now read-only.

WebSocket Support #35

Open
SamCHogg opened this issue Jul 30, 2019 · 3 comments
Open

WebSocket Support #35

SamCHogg opened this issue Jul 30, 2019 · 3 comments

Comments

@SamCHogg
Copy link

Environment:

  • Kubernetes distribution: EKS
  • Kubernetes version: v1.11.8-eks-7c34c0
  • Osiris version: 0.0.1-2019.05.21.13.53.23-4f8deee
  • Install method: helm install osiris/osiris-edge --name osiris --namespace osiris-system --devel

What happened?
I have been starting to use this project to scale down our preview environments (which is really awesome btw!). However I came across issues when I tried to use this one of our services which relies on websockets. The browser gets a '502 Bad Gateway' response from the websocket requests. Checking the logs from the proxy sidecar I see this error:

http: proxy error: internal error: 101 switching protocols response with non-writable body

So I was wondering if websockets are supported, and what I might be missing to get this working?

What you expected to happen?
Websocket requests work correctly through the proxy.

@SamCHogg
Copy link
Author

Looking at the implementation here:

func (p *ReverseProxy) handleUpgradeResponse(rw http.ResponseWriter, req *http.Request, res *http.Response) {
reqUpType := upgradeType(req.Header)
resUpType := upgradeType(res.Header)
if reqUpType != resUpType {
p.getErrorHandler()(rw, req, fmt.Errorf("backend tried to switch protocol %q when %q was requested", resUpType, reqUpType))
return
}
copyHeader(res.Header, rw.Header())
hj, ok := rw.(http.Hijacker)
if !ok {
p.getErrorHandler()(rw, req, fmt.Errorf("can't switch protocols using non-Hijacker ResponseWriter type %T", rw))
return
}
backConn, ok := res.Body.(io.ReadWriteCloser)
if !ok {
p.getErrorHandler()(rw, req, fmt.Errorf("internal error: 101 switching protocols response with non-writable body"))
return
}
defer backConn.Close()
conn, brw, err := hj.Hijack()
if err != nil {
p.getErrorHandler()(rw, req, fmt.Errorf("Hijack failed on protocol switch: %v", err))
return
}
defer conn.Close()
res.Body = nil // so res.Write only writes the headers; we have res.Body in backConn above
if err := res.Write(brw); err != nil {
p.getErrorHandler()(rw, req, fmt.Errorf("response write: %v", err))
return
}
if err := brw.Flush(); err != nil {
p.getErrorHandler()(rw, req, fmt.Errorf("response flush: %v", err))
return
}
errc := make(chan error, 1)
spc := switchProtocolCopier{user: conn, backend: backConn}
go spc.copyToBackend(errc)
go spc.copyFromBackend(errc)
<-errc
return
}

And based on this comment: golang/go#26937 (comment)

I see that the implementation used relies on Go 1.12 features, where as I believe this project is complied with Go 1.11. The comment below shows an implementation which works with 1.11.

@krancour
Copy link
Contributor

There is no support for web sockets at the moment, nor do I believe it's planned. (This project is relatively dormant at the moment.)

I see that the implementation used relies on Go 1.12 features, where as I believe this project is complied with Go 1.11.

Relevant Go 1.12 features were replicated in our own source tree. Now that Go 1.12 is available, we can probably undo that.

@SamCHogg
Copy link
Author

Relevant Go 1.12 features were replicated in our own source tree. Now that Go 1.12 is available, we can probably undo that.

Ah, I see that now. Makes sense.

There is no support for web sockets at the moment, nor do I believe it's planned. (This project is relatively dormant at the moment.)

That is sad to hear, especially with how some projects rely on websockets, but it's at least good to know.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants