DialContext creates a new client connection. Use requestHeader to specify the origin (Origin), subprotocols (Sec-WebSocket-Protocol) and cookies (Cookie). Use the response.Header to get the selected subprotocol (Sec-WebSocket-Protocol) and cookies (Set-Cookie). The context will be used in the reque
(ctx context.Context, urlStr string, requestHeader http.Header)
| 158 | // etcetera. The response body may not contain the entire response and does not |
| 159 | // need to be closed by the application. |
| 160 | func (d *Dialer) DialContext(ctx context.Context, urlStr string, requestHeader http.Header) (*Conn, *http.Response, error) { |
| 161 | if d == nil { |
| 162 | d = &nilDialer |
| 163 | } |
| 164 | |
| 165 | challengeKey, err := generateChallengeKey() |
| 166 | if err != nil { |
| 167 | return nil, nil, err |
| 168 | } |
| 169 | |
| 170 | u, err := url.Parse(urlStr) |
| 171 | if err != nil { |
| 172 | return nil, nil, err |
| 173 | } |
| 174 | |
| 175 | switch u.Scheme { |
| 176 | case "ws": |
| 177 | u.Scheme = "http" |
| 178 | case "wss": |
| 179 | u.Scheme = "https" |
| 180 | default: |
| 181 | return nil, nil, errMalformedURL |
| 182 | } |
| 183 | |
| 184 | if u.User != nil { |
| 185 | // User name and password are not allowed in websocket URIs. |
| 186 | return nil, nil, errMalformedURL |
| 187 | } |
| 188 | |
| 189 | req := &http.Request{ |
| 190 | Method: http.MethodGet, |
| 191 | URL: u, |
| 192 | Proto: "HTTP/1.1", |
| 193 | ProtoMajor: 1, |
| 194 | ProtoMinor: 1, |
| 195 | Header: make(http.Header), |
| 196 | Host: u.Host, |
| 197 | } |
| 198 | req = req.WithContext(ctx) |
| 199 | |
| 200 | // Set the cookies present in the cookie jar of the dialer |
| 201 | if d.Jar != nil { |
| 202 | for _, cookie := range d.Jar.Cookies(u) { |
| 203 | req.AddCookie(cookie) |
| 204 | } |
| 205 | } |
| 206 | |
| 207 | // Set the request headers using the capitalization for names and values in |
| 208 | // RFC examples. Although the capitalization shouldn't matter, there are |
| 209 | // servers that depend on it. The Header.Set method is not used because the |
| 210 | // method canonicalizes the header names. |
| 211 | req.Header["Upgrade"] = []string{"websocket"} |
| 212 | req.Header["Connection"] = []string{"Upgrade"} |
| 213 | req.Header["Sec-WebSocket-Key"] = []string{challengeKey} |
| 214 | req.Header["Sec-WebSocket-Version"] = []string{"13"} |
| 215 | if len(d.Subprotocols) > 0 { |
| 216 | req.Header["Sec-WebSocket-Protocol"] = []string{strings.Join(d.Subprotocols, ", ")} |
| 217 | } |