@@ -3,6 +3,7 @@ package websocketproxy
3
3
4
4
import (
5
5
"fmt"
6
+ "io"
6
7
"log"
7
8
"net"
8
9
"net/http"
@@ -133,7 +134,17 @@ func (w *WebsocketProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
133
134
// http://tools.ietf.org/html/draft-ietf-hybi-websocket-multiplexing-01
134
135
connBackend , resp , err := dialer .Dial (backendURL .String (), requestHeader )
135
136
if err != nil {
136
- log .Printf ("websocketproxy: couldn't dial to remote backend url %s\n " , err )
137
+ log .Printf ("websocketproxy: couldn't dial to remote backend url %s" , err )
138
+ if resp != nil {
139
+ // If the WebSocket handshake fails, ErrBadHandshake is returned
140
+ // along with a non-nil *http.Response so that callers can handle
141
+ // redirects, authentication, etcetera.
142
+ if err := copyResponse (rw , resp ); err != nil {
143
+ log .Printf ("websocketproxy: couldn't write response after failed remote backend handshake: %s" , err )
144
+ }
145
+ } else {
146
+ http .Error (rw , http .StatusText (http .StatusServiceUnavailable ), http .StatusServiceUnavailable )
147
+ }
137
148
return
138
149
}
139
150
defer connBackend .Close ()
@@ -156,7 +167,7 @@ func (w *WebsocketProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
156
167
// Also pass the header that we gathered from the Dial handshake.
157
168
connPub , err := upgrader .Upgrade (rw , req , upgradeHeader )
158
169
if err != nil {
159
- log .Printf ("websocketproxy: couldn't upgrade %s\n " , err )
170
+ log .Printf ("websocketproxy: couldn't upgrade %s" , err )
160
171
return
161
172
}
162
173
defer connPub .Close ()
@@ -200,3 +211,20 @@ func (w *WebsocketProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
200
211
log .Printf (message , err )
201
212
}
202
213
}
214
+
215
+ func copyHeader (dst , src http.Header ) {
216
+ for k , vv := range src {
217
+ for _ , v := range vv {
218
+ dst .Add (k , v )
219
+ }
220
+ }
221
+ }
222
+
223
+ func copyResponse (rw http.ResponseWriter , resp * http.Response ) error {
224
+ copyHeader (rw .Header (), resp .Header )
225
+ rw .WriteHeader (resp .StatusCode )
226
+ defer resp .Body .Close ()
227
+
228
+ _ , err := io .Copy (rw , resp .Body )
229
+ return err
230
+ }
0 commit comments