@@ -56,38 +56,55 @@ func NewProxy(target *url.URL) *WebsocketProxy {
56
56
57
57
// ServeHTTP implements the http.Handler that proxies WebSocket connections.
58
58
func (w * WebsocketProxy ) ServeHTTP (rw http.ResponseWriter , req * http.Request ) {
59
- upgrader := w .Upgrader
60
- if w .Upgrader == nil {
61
- upgrader = DefaultUpgrader
62
- }
63
-
64
- connPub , err := upgrader .Upgrade (rw , req , nil )
65
- if err != nil {
66
- log .Printf ("websocketproxy: couldn't upgrade %s\n " , err )
67
- return
68
- }
69
- defer connPub .Close ()
70
-
71
59
backendURL := w .Backend (req )
72
60
73
61
dialer := w .Dialer
74
62
if w .Dialer == nil {
75
63
dialer = DefaultDialer
76
64
}
77
65
78
- connBackend , _ , err := dialer .Dial (backendURL .String (), nil )
66
+ // Pass headers from the incoming request to the dialer to forward them to
67
+ // the final destinations.
68
+ h := http.Header {}
69
+ h .Add ("Origin" , req .Header .Get ("Origin" ))
70
+ protocols := req .Header ["Sec-WebSocket-Protocol" ]
71
+ for _ , prot := range protocols {
72
+ h .Add ("Sec-WebSocket-Protocol" , prot )
73
+ }
74
+ cookies := req .Header ["Cookie" ]
75
+ for _ , cookie := range cookies {
76
+ h .Add ("Cookie" , cookie )
77
+ }
78
+
79
+ // Connect to the backend url, also pass the headers we prepared above.
80
+ connBackend , resp , err := dialer .Dial (backendURL .String (), h )
79
81
if err != nil {
80
82
log .Printf ("websocketproxy: couldn't dial to remote backend url %s\n " , err )
81
83
return
82
84
}
83
85
defer connBackend .Close ()
84
86
87
+ upgrader := w .Upgrader
88
+ if w .Upgrader == nil {
89
+ upgrader = DefaultUpgrader
90
+ }
91
+
92
+ // Now upgrade the existing incoming request to a WebSocket connection.
93
+ // Also pass the responseHeader that we gathered from the Dial handshake.
94
+ connPub , err := upgrader .Upgrade (rw , req , resp .Header )
95
+ if err != nil {
96
+ log .Printf ("websocketproxy: couldn't upgrade %s\n " , err )
97
+ return
98
+ }
99
+ defer connPub .Close ()
100
+
85
101
errc := make (chan error , 2 )
86
102
cp := func (dst io.Writer , src io.Reader ) {
87
103
_ , err := io .Copy (dst , src )
88
104
errc <- err
89
105
}
90
106
107
+ // Start our proxy now, after we setup everything.
91
108
go cp (connBackend .UnderlyingConn (), connPub .UnderlyingConn ())
92
109
go cp (connPub .UnderlyingConn (), connBackend .UnderlyingConn ())
93
110
<- errc
0 commit comments