From 57c53df2246eb79d77245e8f2cc9efe03f997c14 Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Fri, 25 Mar 2016 20:04:45 +0100 Subject: Add (working) stub for WebSocket Proxy --- ws.go | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 ws.go (limited to 'ws.go') diff --git a/ws.go b/ws.go new file mode 100644 index 0000000..a8f85b6 --- /dev/null +++ b/ws.go @@ -0,0 +1,68 @@ +package main + +import ( + "io" + "log" + "net" + "net/http" + "net/url" + "strings" +) + +type WebSocketProxy struct { + Director func(*http.Request) +} + +func (p *WebSocketProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) { + p.Director(r) + + d, err := net.Dial("tcp", r.URL.Host) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + defer d.Close() + hj, ok := w.(http.Hijacker) + if !ok { + http.Error(w, "Not a hijacker", http.StatusInternalServerError) + return + } + nc, _, err := hj.Hijack() + if err != nil { + log.Println(err) + return + } + defer nc.Close() + + err = r.Write(d) + if err != nil { + log.Println(err) + return + } + + errc := make(chan error, 2) + cp := func(dst io.Writer, src io.Reader) { + _, err := io.Copy(dst, src) + errc <- err + } + go cp(d, nc) + go cp(nc, d) + <-errc +} + +func NewWebSocketProxy(target *url.URL) *WebSocketProxy { + director := func(req *http.Request) { + req.URL.Scheme = target.Scheme + req.URL.Host = target.Host + } + return &WebSocketProxy{Director: director} +} + +func isWebsocket(req *http.Request) bool { + conn := req.Header.Get("Connection") + if strings.ToLower(conn) == "upgrade" { + upgrade := req.Header.Get("Upgrade") + return strings.ToLower(upgrade) == "websocket" + } + return false +} -- cgit v1.2.3