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

Commit 34cc73a

Browse files
committed
Disable automatic Sec-WebSocket-Protocol header, closes #179
1 parent e606fca commit 34cc73a

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

packages/http-server/src/index.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,13 @@ export async function createServer<Plugins extends HTTPPluginSignatures>(
367367
const { WebSocketServer }: typeof import("ws") = require("ws");
368368

369369
// Setup WebSocket servers
370-
const webSocketServer = new WebSocketServer({ noServer: true });
370+
const webSocketServer = new WebSocketServer({
371+
noServer: true,
372+
// Disable automatic handling of `Sec-WebSocket-Protocol` header, Cloudflare
373+
// Workers require users to include this header themselves in `Response`s:
374+
// https://github.com/cloudflare/miniflare/issues/179
375+
handleProtocols: () => false,
376+
});
371377
const liveReloadServer = new WebSocketServer({ noServer: true });
372378

373379
// Add custom headers included in response to WebSocket upgrade requests

packages/http-server/test/index.spec.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -684,6 +684,39 @@ test("createServer: includes headers from web socket upgrade response", async (t
684684
t.not(req.headers["sec-websocket-accept"], ":(");
685685
t.deepEqual(req.headers["set-cookie"], ["key=value"]);
686686
});
687+
test("createServer: handles web socket upgrade response with Sec-WebSocket-Protocol header", async (t) => {
688+
// https://github.com/cloudflare/miniflare/issues/179
689+
const mf = useMiniflareWithHandler(
690+
{ HTTPPlugin, WebSocketPlugin },
691+
{},
692+
async (globals) => {
693+
const [client, worker] = Object.values(new globals.WebSocketPair());
694+
worker.accept();
695+
worker.addEventListener("message", (e: MessageEvent) => {
696+
worker.send(`worker:${e.data}`);
697+
});
698+
return new globals.Response(null, {
699+
status: 101,
700+
webSocket: client,
701+
headers: { "Sec-WebSocket-Protocol": "protocol2" },
702+
});
703+
}
704+
);
705+
const port = await listen(t, await createServer(mf));
706+
707+
const ws = new StandardWebSocket(`ws://localhost:${port}`, [
708+
"protocol1",
709+
"protocol2",
710+
"protocol3",
711+
]);
712+
ws.addListener("upgrade", (req) => {
713+
t.is(req.headers["sec-websocket-protocol"], "protocol2");
714+
});
715+
const [eventTrigger, eventPromise] = triggerPromise<Data>();
716+
ws.addEventListener("message", (e) => eventTrigger(e.data));
717+
ws.addEventListener("open", () => ws.send("hello"));
718+
t.is(await eventPromise, "worker:hello");
719+
});
687720
test("createServer: expects status 101 and web socket response for successful upgrades", async (t) => {
688721
const log = new TestLog();
689722
log.error = (message) => log.logWithLevel(LogLevel.ERROR, message.toString());

0 commit comments

Comments
 (0)