@@ -19,7 +19,7 @@ type DialOptions struct {
19
19
// HTTPClient is the http client used for the handshake.
20
20
// Its Transport must use HTTP/1.1 and must return writable bodies
21
21
// for WebSocket handshakes. This was introduced in Go 1.12.
22
- // http.Transport does this correctly.
22
+ // http.Transport does this all correctly.
23
23
HTTPClient * http.Client
24
24
25
25
// HTTPHeader specifies the HTTP headers included in the handshake request.
@@ -35,6 +35,9 @@ type DialOptions struct {
35
35
var secWebSocketKey = base64 .StdEncoding .EncodeToString (make ([]byte , 16 ))
36
36
37
37
// Dial performs a WebSocket handshake on the given url with the given options.
38
+ // The response is the WebSocket handshake response from the server.
39
+ // If an error occurs, the returned response may be non nil. However, you can only
40
+ // read the first 1024 bytes of its body.
38
41
func Dial (ctx context.Context , u string , opts DialOptions ) (* Conn , * http.Response , error ) {
39
42
c , r , err := dial (ctx , u , opts )
40
43
if err != nil {
@@ -48,7 +51,7 @@ func dial(ctx context.Context, u string, opts DialOptions) (_ *Conn, _ *http.Res
48
51
opts .HTTPClient = http .DefaultClient
49
52
}
50
53
if opts .HTTPClient .Timeout > 0 {
51
- return nil , nil , xerrors .Errorf ("please use context for cancellation instead of http.Client.Timeout; see issue nhooyr.io/ websocket# 67" )
54
+ return nil , nil , xerrors .Errorf ("please use context for cancellation instead of http.Client.Timeout; see https://github.com/nhooyr/ websocket/issues/ 67" )
52
55
}
53
56
if opts .HTTPHeader == nil {
54
57
opts .HTTPHeader = http.Header {}
@@ -65,7 +68,7 @@ func dial(ctx context.Context, u string, opts DialOptions) (_ *Conn, _ *http.Res
65
68
case "wss" :
66
69
parsedURL .Scheme = "https"
67
70
default :
68
- return nil , nil , xerrors .Errorf ("unexpected url scheme scheme : %q" , parsedURL .Scheme )
71
+ return nil , nil , xerrors .Errorf ("unexpected url scheme: %q" , parsedURL .Scheme )
69
72
}
70
73
71
74
req , _ := http .NewRequest ("GET" , parsedURL .String (), nil )
@@ -84,13 +87,12 @@ func dial(ctx context.Context, u string, opts DialOptions) (_ *Conn, _ *http.Res
84
87
return nil , nil , xerrors .Errorf ("failed to send handshake request: %w" , err )
85
88
}
86
89
defer func () {
87
- respBody := resp .Body
88
90
if err != nil {
89
- // We read a bit of the body for better debugging.
91
+ // We read a bit of the body for easier debugging.
90
92
r := io .LimitReader (resp .Body , 1024 )
91
93
b , _ := ioutil .ReadAll (r )
94
+ resp .Body .Close ()
92
95
resp .Body = ioutil .NopCloser (bytes .NewReader (b ))
93
- respBody .Close ()
94
96
}
95
97
}()
96
98
@@ -104,7 +106,6 @@ func dial(ctx context.Context, u string, opts DialOptions) (_ *Conn, _ *http.Res
104
106
return nil , resp , xerrors .Errorf ("response body is not a read write closer: %T" , rwc )
105
107
}
106
108
107
- // TODO pool bufio
108
109
c := & Conn {
109
110
subprotocol : resp .Header .Get ("Sec-WebSocket-Protocol" ),
110
111
br : bufio .NewReader (rwc ),
@@ -123,11 +124,11 @@ func verifyServerResponse(resp *http.Response) error {
123
124
}
124
125
125
126
if ! headerValuesContainsToken (resp .Header , "Connection" , "Upgrade" ) {
126
- return xerrors .Errorf ("websocket protocol violation: Connection header does not contain Upgrade: %q " , resp .Header .Get ("Connection" ))
127
+ return xerrors .Errorf ("websocket protocol violation: Connection header %q does not contain Upgrade" , resp .Header .Get ("Connection" ))
127
128
}
128
129
129
130
if ! headerValuesContainsToken (resp .Header , "Upgrade" , "WebSocket" ) {
130
- return xerrors .Errorf ("websocket protocol violation: Upgrade header does not contain websocket: %q " , resp .Header .Get ("Upgrade" ))
131
+ return xerrors .Errorf ("websocket protocol violation: Upgrade header %q does not contain websocket" , resp .Header .Get ("Upgrade" ))
131
132
}
132
133
133
134
// We do not care about Sec-WebSocket-Accept because it does not matter.
0 commit comments