Skip to content

Commit

Permalink
feat(ws): protocol & version support (denoland/deno#8505)
Browse files Browse the repository at this point in the history
Co-authored-by: Tom Wieland <tom.wieland@gmail.com>
  • Loading branch information
2 people authored and caspervonb committed Jan 31, 2021
1 parent c7288f3 commit 805d279
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 6 deletions.
19 changes: 14 additions & 5 deletions ws/mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -427,13 +427,22 @@ export async function acceptWebSocket(req: {
throw new Error("sec-websocket-key is not provided");
}
const secAccept = createSecAccept(secKey);
const newHeaders = new Headers({
Upgrade: "websocket",
Connection: "Upgrade",
"Sec-WebSocket-Accept": secAccept,
});
const secProtocol = headers.get("sec-websocket-protocol");
if (typeof secProtocol === "string") {
newHeaders.set("Sec-WebSocket-Protocol", secProtocol);
}
const secVersion = headers.get("sec-websocket-version");
if (typeof secVersion === "string") {
newHeaders.set("Sec-WebSocket-Version", secVersion);
}
await writeResponse(bufWriter, {
status: 101,
headers: new Headers({
Upgrade: "websocket",
Connection: "Upgrade",
"Sec-WebSocket-Accept": secAccept,
}),
headers: newHeaders,
});
return sock;
}
Expand Down
41 changes: 40 additions & 1 deletion ws/test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { BufReader, BufWriter } from "../io/bufio.ts";
import { assert, assertEquals, assertThrowsAsync } from "../testing/asserts.ts";
import {
assert,
assertEquals,
assertThrowsAsync,
fail,
} from "../testing/asserts.ts";
import { TextProtoReader } from "../textproto/mod.ts";
import * as bytes from "../bytes/mod.ts";
import {
acceptable,
acceptWebSocket,
createSecAccept,
createSecKey,
createWebSocket,
Expand All @@ -16,6 +22,8 @@ import {
} from "./mod.ts";
import { decode, encode } from "../encoding/utf8.ts";
import { delay } from "../async/delay.ts";
import { serve } from "../http/server.ts";
import { deferred } from "../async/deferred.ts";

Deno.test("[ws] read unmasked text frame", async () => {
// unmasked single text frame with payload "Hello"
Expand Down Expand Up @@ -454,3 +462,34 @@ Deno.test("[ws] WebSocket should act as asyncIterator", async () => {
assertEquals(events[1], "Hello");
assertEquals(events[2], { code: 1011, reason: "42" });
});

Deno.test("[ws] WebSocket protocol", async () => {
const promise = deferred();
const server = serve({ port: 5839 });

const ws = new WebSocket("ws://localhost:5839", ["foo", "bar"]);
ws.onopen = () => {
assertEquals(ws.protocol, "foo, bar");
ws.close();
};
ws.onerror = () => fail();
ws.onclose = () => {
server.close();
promise.resolve();
};

const x = await server[Symbol.asyncIterator]().next();
if (!x.done) {
const { conn, r: bufReader, w: bufWriter, headers } = x.value;
await acceptWebSocket({
conn,
bufReader,
bufWriter,
headers,
});

await promise;
} else {
fail();
}
});

0 comments on commit 805d279

Please sign in to comment.