(url, protocols, client, handler, options)
| 15156 | var crypto = runtimeFeatures.has("crypto") ? require("node:crypto") : null; |
| 15157 | var warningEmitted = false; |
| 15158 | function establishWebSocketConnection(url, protocols, client, handler, options) { |
| 15159 | const requestURL = url; |
| 15160 | requestURL.protocol = url.protocol === "ws:" ? "http:" : "https:"; |
| 15161 | const request = makeRequest({ |
| 15162 | urlList: [requestURL], |
| 15163 | client, |
| 15164 | serviceWorkers: "none", |
| 15165 | referrer: "no-referrer", |
| 15166 | mode: "websocket", |
| 15167 | credentials: "include", |
| 15168 | cache: "no-store", |
| 15169 | redirect: "error", |
| 15170 | useURLCredentials: true |
| 15171 | }); |
| 15172 | if (options.headers) { |
| 15173 | const headersList = getHeadersList(new Headers(options.headers)); |
| 15174 | request.headersList = headersList; |
| 15175 | } |
| 15176 | const keyValue = crypto.randomBytes(16).toString("base64"); |
| 15177 | request.headersList.append("sec-websocket-key", keyValue, true); |
| 15178 | request.headersList.append("sec-websocket-version", "13", true); |
| 15179 | for (const protocol of protocols) { |
| 15180 | request.headersList.append("sec-websocket-protocol", protocol, true); |
| 15181 | } |
| 15182 | const permessageDeflate = "permessage-deflate; client_max_window_bits"; |
| 15183 | request.headersList.append("sec-websocket-extensions", permessageDeflate, true); |
| 15184 | const controller = fetching({ |
| 15185 | request, |
| 15186 | useParallelQueue: true, |
| 15187 | dispatcher: options.dispatcher, |
| 15188 | processResponse(response) { |
| 15189 | if (response.type === "error" || response.status !== 101) { |
| 15190 | if (response.socket?.session == null) { |
| 15191 | failWebsocketConnection(handler, 1002, "Received network error or non-101 status code.", response.error); |
| 15192 | return; |
| 15193 | } |
| 15194 | if (response.status !== 200) { |
| 15195 | failWebsocketConnection(handler, 1002, "Received network error or non-200 status code.", response.error); |
| 15196 | return; |
| 15197 | } |
| 15198 | } |
| 15199 | if (warningEmitted === false && response.socket?.session != null) { |
| 15200 | process.emitWarning("WebSocket over HTTP2 is experimental, and subject to change.", "ExperimentalWarning"); |
| 15201 | warningEmitted = true; |
| 15202 | } |
| 15203 | if (protocols.length !== 0 && !response.headersList.get("Sec-WebSocket-Protocol")) { |
| 15204 | failWebsocketConnection(handler, 1002, "Server did not respond with sent protocols."); |
| 15205 | return; |
| 15206 | } |
| 15207 | if (response.socket.session == null && response.headersList.get("Upgrade")?.toLowerCase() !== "websocket") { |
| 15208 | failWebsocketConnection(handler, 1002, 'Server did not set Upgrade header to "websocket".'); |
| 15209 | return; |
| 15210 | } |
| 15211 | if (response.socket.session == null && response.headersList.get("Connection")?.toLowerCase() !== "upgrade") { |
| 15212 | failWebsocketConnection(handler, 1002, 'Server did not set Connection header to "upgrade".'); |
| 15213 | return; |
| 15214 | } |
| 15215 | const secWSAccept = response.headersList.get("Sec-WebSocket-Accept"); |
no test coverage detected