(ctx context.Context, urls string, opts *DialOptions, rand io.Reader)
| 122 | } |
| 123 | |
| 124 | func dial(ctx context.Context, urls string, opts *DialOptions, rand io.Reader) (_ *Conn, _ *http.Response, err error) { |
| 125 | defer errd.Wrap(&err, "failed to WebSocket dial") |
| 126 | |
| 127 | var cancel context.CancelFunc |
| 128 | ctx, cancel, opts = opts.cloneWithDefaults(ctx) |
| 129 | if cancel != nil { |
| 130 | defer cancel() |
| 131 | } |
| 132 | |
| 133 | secWebSocketKey, err := secWebSocketKey(rand) |
| 134 | if err != nil { |
| 135 | return nil, nil, fmt.Errorf("failed to generate Sec-WebSocket-Key: %w", err) |
| 136 | } |
| 137 | |
| 138 | var copts *compressionOptions |
| 139 | if opts.CompressionMode != CompressionDisabled { |
| 140 | copts = opts.CompressionMode.opts() |
| 141 | } |
| 142 | |
| 143 | resp, err := handshakeRequest(ctx, urls, opts, copts, secWebSocketKey) |
| 144 | if err != nil { |
| 145 | return nil, resp, err |
| 146 | } |
| 147 | respBody := resp.Body |
| 148 | resp.Body = nil |
| 149 | defer func() { |
| 150 | if err != nil { |
| 151 | // We read a bit of the body for easier debugging. |
| 152 | r := io.LimitReader(respBody, 1024) |
| 153 | |
| 154 | timer := time.AfterFunc(time.Second*3, func() { |
| 155 | respBody.Close() |
| 156 | }) |
| 157 | defer timer.Stop() |
| 158 | |
| 159 | b, _ := io.ReadAll(r) |
| 160 | respBody.Close() |
| 161 | resp.Body = io.NopCloser(bytes.NewReader(b)) |
| 162 | } |
| 163 | }() |
| 164 | |
| 165 | copts, err = verifyServerResponse(opts, copts, secWebSocketKey, resp) |
| 166 | if err != nil { |
| 167 | return nil, resp, err |
| 168 | } |
| 169 | |
| 170 | rwc, ok := respBody.(io.ReadWriteCloser) |
| 171 | if !ok { |
| 172 | return nil, resp, fmt.Errorf("response body is not a io.ReadWriteCloser: %T", respBody) |
| 173 | } |
| 174 | |
| 175 | return newConn(connConfig{ |
| 176 | subprotocol: resp.Header.Get("Sec-WebSocket-Protocol"), |
| 177 | rwc: rwc, |
| 178 | client: true, |
| 179 | copts: copts, |
| 180 | flateThreshold: opts.CompressionThreshold, |
| 181 | onPingReceived: opts.OnPingReceived, |
no test coverage detected
searching dependent graphs…