Skip to content
This repository was archived by the owner on Mar 13, 2025. It is now read-only.

Commit 733344d

Browse files
committed
Require http/https protocol for WebSocket upgrades
1 parent 210d57d commit 733344d

File tree

4 files changed

+34
-11
lines changed

4 files changed

+34
-11
lines changed

packages/core/src/standards/http.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -477,12 +477,7 @@ export function createCompatFetch(
477477
? input.url
478478
: input.toString()
479479
);
480-
if (
481-
url.protocol !== "http:" &&
482-
url.protocol !== "https:" &&
483-
url.protocol !== "ws:" &&
484-
url.protocol !== "wss:"
485-
) {
480+
if (url.protocol !== "http:" && url.protocol !== "https:") {
486481
if (refusesUnknown) {
487482
throw new TypeError(`Fetch API cannot load: ${url.toString()}`);
488483
} else {

packages/core/test/standards/http.spec.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -610,15 +610,13 @@ test("createCompatFetch: refuses unknown protocols if compatibility flag enabled
610610
message: `Fetch API cannot load: ${upstream.toString()}`,
611611
});
612612
});
613-
test("createCompatFetch: recognises http, https, ws, and wss as known protocols", async (t) => {
613+
test("createCompatFetch: recognises http and https as known protocols", async (t) => {
614614
const fetch = createCompatFetch(
615615
new Compatibility(undefined, ["fetch_refuses_unknown_protocols"]),
616616
async () => new Response("upstream")
617617
);
618618
t.is(await (await fetch("http://localhost/")).text(), "upstream");
619619
t.is(await (await fetch("https://localhost/")).text(), "upstream");
620-
t.is(await (await fetch("ws://localhost/")).text(), "upstream");
621-
t.is(await (await fetch("wss://localhost/")).text(), "upstream");
622620
});
623621
test("createCompatFetch: rewrites urls of all types of fetch inputs", async (t) => {
624622
const { http: upstream } = await useServer(t, (req, res) => {

packages/web-sockets/src/fetch.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { URL } from "url";
12
import {
23
Request,
34
RequestInfo,
@@ -28,7 +29,14 @@ export async function upgradingFetch(
2829
for (const [key, value] of request.headers.entries()) {
2930
headers[key] = value;
3031
}
31-
const ws = new StandardWebSocket(request.url, {
32+
const url = new URL(request.url);
33+
if (url.protocol !== "http:" && url.protocol !== "https:") {
34+
throw new TypeError(
35+
`Fetch API cannot load: ${url.toString()}.\nMake sure you're using http(s):// URLs for WebSocket requests via fetch.`
36+
);
37+
}
38+
url.protocol = url.protocol.replace("http", "ws");
39+
const ws = new StandardWebSocket(url, {
3240
followRedirects: request.redirect === "follow",
3341
headers,
3442
});

packages/web-sockets/test/fetch.spec.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ test("upgradingFetch: performs web socket upgrade", async (t) => {
3838
ws.send(req.headers["user-agent"]);
3939
ws.addEventListener("message", ({ data }) => ws.send(data));
4040
});
41-
const res = await upgradingFetch(server.ws, {
41+
const res = await upgradingFetch(server.http, {
4242
headers: { upgrade: "websocket", "user-agent": "Test" },
4343
});
4444
const webSocket = res.webSocket;
@@ -57,6 +57,28 @@ test("upgradingFetch: performs web socket upgrade", async (t) => {
5757
await eventPromise;
5858
t.deepEqual(messages, ["hello client", "Test", "hello server"]);
5959
});
60+
test("upgradingFetch: throws on ws(s) protocols", async (t) => {
61+
await t.throwsAsync(
62+
upgradingFetch("ws://localhost/", {
63+
headers: { upgrade: "websocket" },
64+
}),
65+
{
66+
instanceOf: TypeError,
67+
message:
68+
"Fetch API cannot load: ws://localhost/.\nMake sure you're using http(s):// URLs for WebSocket requests via fetch.",
69+
}
70+
);
71+
await t.throwsAsync(
72+
upgradingFetch("wss://localhost/", {
73+
headers: { upgrade: "websocket" },
74+
}),
75+
{
76+
instanceOf: TypeError,
77+
message:
78+
"Fetch API cannot load: wss://localhost/.\nMake sure you're using http(s):// URLs for WebSocket requests via fetch.",
79+
}
80+
);
81+
});
6082
test("upgradingFetch: requires GET for web socket upgrade", async (t) => {
6183
const server = await useServer(
6284
t,

0 commit comments

Comments
 (0)