summaryrefslogtreecommitdiff
path: root/cli/tests/unit/websocket_test.ts
diff options
context:
space:
mode:
Diffstat (limited to 'cli/tests/unit/websocket_test.ts')
-rw-r--r--cli/tests/unit/websocket_test.ts738
1 files changed, 0 insertions, 738 deletions
diff --git a/cli/tests/unit/websocket_test.ts b/cli/tests/unit/websocket_test.ts
deleted file mode 100644
index 42681c187..000000000
--- a/cli/tests/unit/websocket_test.ts
+++ /dev/null
@@ -1,738 +0,0 @@
-// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
-import { assert, assertEquals, assertThrows, fail } from "./test_util.ts";
-
-const servePort = 4248;
-const serveUrl = `ws://localhost:${servePort}/`;
-
-Deno.test({ permissions: "none" }, function websocketPermissionless() {
- assertThrows(
- () => new WebSocket("ws://localhost"),
- Deno.errors.PermissionDenied,
- );
-});
-
-Deno.test(async function websocketConstructorTakeURLObjectAsParameter() {
- const { promise, resolve, reject } = Promise.withResolvers<void>();
- const ws = new WebSocket(new URL("ws://localhost:4242/"));
- assertEquals(ws.url, "ws://localhost:4242/");
- ws.onerror = (e) => reject(e);
- ws.onopen = () => ws.close();
- ws.onclose = () => {
- resolve();
- };
- await promise;
-});
-
-Deno.test(async function websocketH2SendSmallPacket() {
- const { promise, resolve, reject } = Promise.withResolvers<void>();
- const ws = new WebSocket(new URL("wss://localhost:4249/"));
- assertEquals(ws.url, "wss://localhost:4249/");
- let messageCount = 0;
- ws.onerror = (e) => reject(e);
- ws.onopen = () => {
- ws.send("a".repeat(16));
- ws.send("a".repeat(16));
- ws.send("a".repeat(16));
- };
- ws.onmessage = () => {
- if (++messageCount == 3) {
- ws.close();
- }
- };
- ws.onclose = () => {
- resolve();
- };
- await promise;
-});
-
-Deno.test(async function websocketH2SendLargePacket() {
- const { promise, resolve, reject } = Promise.withResolvers<void>();
- const ws = new WebSocket(new URL("wss://localhost:4249/"));
- assertEquals(ws.url, "wss://localhost:4249/");
- let messageCount = 0;
- ws.onerror = (e) => reject(e);
- ws.onopen = () => {
- ws.send("a".repeat(65000));
- ws.send("a".repeat(65000));
- ws.send("a".repeat(65000));
- };
- ws.onmessage = () => {
- if (++messageCount == 3) {
- ws.close();
- }
- };
- ws.onclose = () => {
- resolve();
- };
- await promise;
-});
-
-Deno.test(async function websocketSendLargePacket() {
- const { promise, resolve, reject } = Promise.withResolvers<void>();
- const ws = new WebSocket(new URL("wss://localhost:4243/"));
- assertEquals(ws.url, "wss://localhost:4243/");
- ws.onerror = (e) => reject(e);
- ws.onopen = () => {
- ws.send("a".repeat(65000));
- };
- ws.onmessage = () => {
- ws.close();
- };
- ws.onclose = () => {
- resolve();
- };
- await promise;
-});
-
-Deno.test(async function websocketSendLargeBinaryPacket() {
- const { promise, resolve, reject } = Promise.withResolvers<void>();
- const ws = new WebSocket(new URL("wss://localhost:4243/"));
- ws.binaryType = "arraybuffer";
- assertEquals(ws.url, "wss://localhost:4243/");
- ws.onerror = (e) => reject(e);
- ws.onopen = () => {
- ws.send(new Uint8Array(65000));
- };
- ws.onmessage = (msg: MessageEvent) => {
- assertEquals(msg.data.byteLength, 65000);
- ws.close();
- };
- ws.onclose = () => {
- resolve();
- };
- await promise;
-});
-
-Deno.test(async function websocketSendLargeBlobPacket() {
- const { promise, resolve, reject } = Promise.withResolvers<void>();
- const ws = new WebSocket(new URL("wss://localhost:4243/"));
- ws.binaryType = "arraybuffer";
- assertEquals(ws.url, "wss://localhost:4243/");
- ws.onerror = (e) => reject(e);
- ws.onopen = () => {
- ws.send(new Blob(["a".repeat(65000)]));
- };
- ws.onmessage = (msg: MessageEvent) => {
- assertEquals(msg.data.byteLength, 65000);
- ws.close();
- };
- ws.onclose = () => {
- resolve();
- };
- await promise;
-});
-
-// https://github.com/denoland/deno/pull/17762
-// https://github.com/denoland/deno/issues/17761
-Deno.test(async function websocketPingPong() {
- const { promise, resolve, reject } = Promise.withResolvers<void>();
- const ws = new WebSocket("ws://localhost:4245/");
- assertEquals(ws.url, "ws://localhost:4245/");
- ws.onerror = (e) => reject(e);
- ws.onmessage = (e) => {
- ws.send(e.data);
- };
- ws.onclose = () => {
- resolve();
- };
- await promise;
- ws.close();
-});
-
-// TODO(mmastrac): This requires us to ignore bad certs
-// Deno.test(async function websocketSecureConnect() {
-// const { promise, resolve } = Promise.withResolvers<void>();
-// const ws = new WebSocket("wss://localhost:4243/");
-// assertEquals(ws.url, "wss://localhost:4243/");
-// ws.onerror = (error) => {
-// console.log(error);
-// fail();
-// };
-// ws.onopen = () => ws.close();
-// ws.onclose = () => {
-// resolve();
-// };
-// await promise;
-// });
-
-// https://github.com/denoland/deno/issues/18700
-Deno.test(
- { sanitizeOps: false, sanitizeResources: false },
- async function websocketWriteLock() {
- const ac = new AbortController();
- const listeningDeferred = Promise.withResolvers<void>();
-
- const server = Deno.serve({
- handler: (req) => {
- const { socket, response } = Deno.upgradeWebSocket(req);
- socket.onopen = function () {
- setTimeout(() => socket.send("Hello"), 500);
- };
- socket.onmessage = function (e) {
- assertEquals(e.data, "Hello");
- ac.abort();
- };
- return response;
- },
- signal: ac.signal,
- onListen: () => listeningDeferred.resolve(),
- hostname: "localhost",
- port: servePort,
- });
-
- await listeningDeferred.promise;
- const deferred = Promise.withResolvers<void>();
- const ws = new WebSocket(serveUrl);
- assertEquals(ws.url, serveUrl);
- ws.onerror = () => fail();
- ws.onmessage = (e) => {
- assertEquals(e.data, "Hello");
- setTimeout(() => {
- ws.send(e.data);
- }, 1000);
- deferred.resolve();
- };
- ws.onclose = () => {
- deferred.resolve();
- };
-
- await Promise.all([deferred.promise, server.finished]);
- ws.close();
- },
-);
-
-// https://github.com/denoland/deno/issues/18775
-Deno.test({
- sanitizeOps: false,
- sanitizeResources: false,
-}, async function websocketDoubleClose() {
- const deferred = Promise.withResolvers<void>();
-
- const ac = new AbortController();
- const listeningDeferred = Promise.withResolvers<void>();
-
- const server = Deno.serve({
- handler: (req) => {
- const { response, socket } = Deno.upgradeWebSocket(req);
- let called = false;
- socket.onopen = () => socket.send("Hello");
- socket.onmessage = () => {
- assert(!called);
- called = true;
- socket.send("bye");
- socket.close();
- };
- socket.onclose = () => ac.abort();
- socket.onerror = () => fail();
- return response;
- },
- signal: ac.signal,
- onListen: () => listeningDeferred.resolve(),
- hostname: "localhost",
- port: servePort,
- });
-
- await listeningDeferred.promise;
-
- const ws = new WebSocket(serveUrl);
- assertEquals(ws.url, serveUrl);
- ws.onerror = () => fail();
- ws.onmessage = (m: MessageEvent) => {
- if (m.data == "Hello") ws.send("bye");
- };
- ws.onclose = () => {
- deferred.resolve();
- };
- await Promise.all([deferred.promise, server.finished]);
-});
-
-// https://github.com/denoland/deno/issues/19483
-Deno.test({
- sanitizeOps: false,
- sanitizeResources: false,
-}, async function websocketCloseFlushes() {
- const deferred = Promise.withResolvers<void>();
-
- const ac = new AbortController();
- const listeningDeferred = Promise.withResolvers<void>();
-
- const server = Deno.serve({
- handler: (req) => {
- const { response, socket } = Deno.upgradeWebSocket(req);
- socket.onopen = () => socket.send("Hello");
- socket.onmessage = () => {
- socket.send("Bye");
- socket.close();
- };
- socket.onclose = () => ac.abort();
- socket.onerror = () => fail();
- return response;
- },
- signal: ac.signal,
- onListen: () => listeningDeferred.resolve(),
- hostname: "localhost",
- port: servePort,
- });
-
- await listeningDeferred.promise;
-
- const ws = new WebSocket(serveUrl);
- assertEquals(ws.url, serveUrl);
- let seenBye = false;
- ws.onerror = () => fail();
- ws.onmessage = ({ data }) => {
- if (data == "Hello") {
- ws.send("Hello!");
- } else {
- assertEquals(data, "Bye");
- seenBye = true;
- }
- };
- ws.onclose = () => {
- deferred.resolve();
- };
- await Promise.all([deferred.promise, server.finished]);
-
- assert(seenBye);
-});
-
-Deno.test(
- { sanitizeOps: false },
- function websocketConstructorWithPrototypePollution() {
- const originalSymbolIterator = Array.prototype[Symbol.iterator];
- try {
- Array.prototype[Symbol.iterator] = () => {
- throw Error("unreachable");
- };
- assertThrows(() => {
- new WebSocket(
- new URL("ws://localhost:4242/"),
- // Allow `Symbol.iterator` to be called in WebIDL conversion to `sequence<DOMString>`
- // deno-lint-ignore no-explicit-any
- ["soap", "soap"].values() as any,
- );
- }, DOMException);
- } finally {
- Array.prototype[Symbol.iterator] = originalSymbolIterator;
- }
- },
-);
-
-Deno.test(async function websocketTlsSocketWorks() {
- const cert = await Deno.readTextFile("cli/tests/testdata/tls/localhost.crt");
- const key = await Deno.readTextFile("cli/tests/testdata/tls/localhost.key");
-
- const messages: string[] = [],
- errors: { server?: Event; client?: Event }[] = [];
- const promise = new Promise((okay, nope) => {
- const ac = new AbortController();
- const server = Deno.serve({
- handler: (req) => {
- const { response, socket } = Deno.upgradeWebSocket(req);
- socket.onopen = () => socket.send("ping");
- socket.onmessage = (e) => {
- messages.push(e.data);
- socket.close();
- };
- socket.onerror = (e) => errors.push({ server: e });
- socket.onclose = () => ac.abort();
- return response;
- },
- signal: ac.signal,
- hostname: "localhost",
- port: servePort,
- cert,
- key,
- });
- setTimeout(() => {
- const ws = new WebSocket(`wss://localhost:${servePort}`);
- ws.onmessage = (e) => {
- messages.push(e.data);
- ws.send("pong");
- };
- ws.onerror = (e) => {
- errors.push({ client: e });
- nope();
- };
- ws.onclose = () => okay(server.finished);
- }, 1000);
- });
-
- const finished = await promise;
-
- assertEquals(errors, []);
- assertEquals(messages, ["ping", "pong"]);
-
- await finished;
-});
-
-// https://github.com/denoland/deno/issues/15340
-Deno.test(
- async function websocketServerFieldInit() {
- const ac = new AbortController();
- const listeningDeferred = Promise.withResolvers<void>();
-
- const server = Deno.serve({
- handler: (req) => {
- const { socket, response } = Deno.upgradeWebSocket(req, {
- idleTimeout: 0,
- });
- socket.onopen = function () {
- assert(typeof socket.url == "string");
- assert(socket.readyState == WebSocket.OPEN);
- assert(socket.protocol == "");
- assert(socket.binaryType == "arraybuffer");
- socket.close();
- };
- socket.onclose = () => ac.abort();
- return response;
- },
- signal: ac.signal,
- onListen: () => listeningDeferred.resolve(),
- hostname: "localhost",
- port: servePort,
- });
-
- await listeningDeferred.promise;
- const deferred = Promise.withResolvers<void>();
- const ws = new WebSocket(serveUrl);
- assertEquals(ws.url, serveUrl);
- ws.onerror = () => fail();
- ws.onclose = () => {
- deferred.resolve();
- };
-
- await Promise.all([deferred.promise, server.finished]);
- },
-);
-
-Deno.test(
- { sanitizeOps: false },
- async function websocketServerGetsGhosted() {
- const ac = new AbortController();
- const listeningDeferred = Promise.withResolvers<void>();
-
- const server = Deno.serve({
- handler: (req) => {
- const { socket, response } = Deno.upgradeWebSocket(req, {
- idleTimeout: 2,
- });
- socket.onerror = () => socket.close();
- socket.onclose = () => ac.abort();
- return response;
- },
- signal: ac.signal,
- onListen: () => listeningDeferred.resolve(),
- hostname: "localhost",
- port: servePort,
- });
-
- await listeningDeferred.promise;
- const r = await fetch("http://localhost:4545/ghost_ws_client");
- assertEquals(r.status, 200);
- await r.body?.cancel();
-
- await server.finished;
- },
-);
-
-Deno.test("invalid scheme", () => {
- assertThrows(() => new WebSocket("foo://localhost:4242"));
-});
-
-Deno.test("fragment", () => {
- assertThrows(() => new WebSocket("ws://localhost:4242/#"));
- assertThrows(() => new WebSocket("ws://localhost:4242/#foo"));
-});
-
-Deno.test("duplicate protocols", () => {
- assertThrows(() => new WebSocket("ws://localhost:4242", ["foo", "foo"]));
-});
-
-Deno.test("invalid server", async () => {
- const { promise, resolve } = Promise.withResolvers<void>();
- const ws = new WebSocket("ws://localhost:2121");
- let err = false;
- ws.onerror = () => {
- err = true;
- };
- ws.onclose = () => {
- if (err) {
- resolve();
- } else {
- fail();
- }
- };
- ws.onopen = () => fail();
- await promise;
-});
-
-Deno.test("connect & close", async () => {
- const { promise, resolve } = Promise.withResolvers<void>();
- const ws = new WebSocket("ws://localhost:4242");
- ws.onerror = () => fail();
- ws.onopen = () => {
- ws.close();
- };
- ws.onclose = () => {
- resolve();
- };
- await promise;
-});
-
-Deno.test("connect & abort", async () => {
- const { promise, resolve } = Promise.withResolvers<void>();
- const ws = new WebSocket("ws://localhost:4242");
- ws.close();
- let err = false;
- ws.onerror = () => {
- err = true;
- };
- ws.onclose = () => {
- if (err) {
- resolve();
- } else {
- fail();
- }
- };
- ws.onopen = () => fail();
- await promise;
-});
-
-Deno.test("connect & close custom valid code", async () => {
- const { promise, resolve } = Promise.withResolvers<void>();
- const ws = new WebSocket("ws://localhost:4242");
- ws.onerror = () => fail();
- ws.onopen = () => ws.close(1000);
- ws.onclose = () => {
- resolve();
- };
- await promise;
-});
-
-Deno.test("connect & close custom invalid code", async () => {
- const { promise, resolve } = Promise.withResolvers<void>();
- const ws = new WebSocket("ws://localhost:4242");
- ws.onerror = () => fail();
- ws.onopen = () => {
- assertThrows(() => ws.close(1001));
- ws.close();
- };
- ws.onclose = () => {
- resolve();
- };
- await promise;
-});
-
-Deno.test("connect & close custom valid reason", async () => {
- const { promise, resolve } = Promise.withResolvers<void>();
- const ws = new WebSocket("ws://localhost:4242");
- ws.onerror = () => fail();
- ws.onopen = () => ws.close(1000, "foo");
- ws.onclose = () => {
- resolve();
- };
- await promise;
-});
-
-Deno.test("connect & close custom invalid reason", async () => {
- const { promise, resolve } = Promise.withResolvers<void>();
- const ws = new WebSocket("ws://localhost:4242");
- ws.onerror = () => fail();
- ws.onopen = () => {
- assertThrows(() => ws.close(1000, "".padEnd(124, "o")));
- ws.close();
- };
- ws.onclose = () => {
- resolve();
- };
- await promise;
-});
-
-Deno.test("echo string", async () => {
- const { promise, resolve } = Promise.withResolvers<void>();
- const ws = new WebSocket("ws://localhost:4242");
- ws.onerror = () => fail();
- ws.onopen = () => ws.send("foo");
- ws.onmessage = (e) => {
- assertEquals(e.data, "foo");
- ws.close();
- };
- ws.onclose = () => {
- resolve();
- };
- await promise;
-});
-
-Deno.test("echo string tls", async () => {
- const deferred1 = Promise.withResolvers<void>();
- const deferred2 = Promise.withResolvers<void>();
- const ws = new WebSocket("wss://localhost:4243");
- ws.onerror = () => fail();
- ws.onopen = () => ws.send("foo");
- ws.onmessage = (e) => {
- assertEquals(e.data, "foo");
- ws.close();
- deferred1.resolve();
- };
- ws.onclose = () => {
- deferred2.resolve();
- };
- await deferred1.promise;
- await deferred2.promise;
-});
-
-Deno.test("websocket error", async () => {
- const { promise, resolve } = Promise.withResolvers<void>();
- const ws = new WebSocket("wss://localhost:4242");
- ws.onopen = () => fail();
- ws.onerror = (err) => {
- assert(err instanceof ErrorEvent);
- assertEquals(
- err.message,
- "NetworkError: failed to connect to WebSocket: received corrupt message of type InvalidContentType",
- );
- resolve();
- };
- await promise;
-});
-
-Deno.test("echo blob with binaryType blob", async () => {
- const { promise, resolve } = Promise.withResolvers<void>();
- const ws = new WebSocket("ws://localhost:4242");
- const blob = new Blob(["foo"]);
- ws.onerror = () => fail();
- ws.onopen = () => ws.send(blob);
- ws.onmessage = (e) => {
- e.data.text().then((actual: string) => {
- blob.text().then((expected) => {
- assertEquals(actual, expected);
- });
- });
- ws.close();
- };
- ws.onclose = () => {
- resolve();
- };
- await promise;
-});
-
-Deno.test("echo blob with binaryType arraybuffer", async () => {
- const { promise, resolve } = Promise.withResolvers<void>();
- const ws = new WebSocket("ws://localhost:4242");
- ws.binaryType = "arraybuffer";
- const blob = new Blob(["foo"]);
- ws.onerror = () => fail();
- ws.onopen = () => ws.send(blob);
- ws.onmessage = (e) => {
- blob.arrayBuffer().then((expected) => {
- assertEquals(e.data, expected);
- });
- ws.close();
- };
- ws.onclose = () => {
- resolve();
- };
- await promise;
-});
-
-Deno.test("echo uint8array with binaryType blob", async () => {
- const { promise, resolve } = Promise.withResolvers<void>();
- const ws = new WebSocket("ws://localhost:4242");
- const uint = new Uint8Array([102, 111, 111]);
- ws.onerror = () => fail();
- ws.onopen = () => ws.send(uint);
- ws.onmessage = (e) => {
- e.data.arrayBuffer().then((actual: ArrayBuffer) => {
- assertEquals(actual, uint.buffer);
- });
- ws.close();
- };
- ws.onclose = () => {
- resolve();
- };
- await promise;
-});
-
-Deno.test("echo uint8array with binaryType arraybuffer", async () => {
- const { promise, resolve } = Promise.withResolvers<void>();
- const ws = new WebSocket("ws://localhost:4242");
- ws.binaryType = "arraybuffer";
- const uint = new Uint8Array([102, 111, 111]);
- ws.onerror = () => fail();
- ws.onopen = () => ws.send(uint);
- ws.onmessage = (e) => {
- assertEquals(e.data, uint.buffer);
- ws.close();
- };
- ws.onclose = () => {
- resolve();
- };
- await promise;
-});
-
-Deno.test("echo arraybuffer with binaryType blob", async () => {
- const { promise, resolve } = Promise.withResolvers<void>();
- const ws = new WebSocket("ws://localhost:4242");
- const buffer = new ArrayBuffer(3);
- ws.onerror = () => fail();
- ws.onopen = () => ws.send(buffer);
- ws.onmessage = (e) => {
- e.data.arrayBuffer().then((actual: ArrayBuffer) => {
- assertEquals(actual, buffer);
- });
- ws.close();
- };
- ws.onclose = () => {
- resolve();
- };
- await promise;
-});
-
-Deno.test("echo arraybuffer with binaryType arraybuffer", async () => {
- const { promise, resolve } = Promise.withResolvers<void>();
- const ws = new WebSocket("ws://localhost:4242");
- ws.binaryType = "arraybuffer";
- const buffer = new ArrayBuffer(3);
- ws.onerror = () => fail();
- ws.onopen = () => ws.send(buffer);
- ws.onmessage = (e) => {
- assertEquals(e.data, buffer);
- ws.close();
- };
- ws.onclose = () => {
- resolve();
- };
- await promise;
-});
-
-Deno.test("Event Handlers order", async () => {
- const { promise, resolve } = Promise.withResolvers<void>();
- const ws = new WebSocket("ws://localhost:4242");
- const arr: number[] = [];
- ws.onerror = () => fail();
- ws.addEventListener("message", () => arr.push(1));
- ws.onmessage = () => fail();
- ws.addEventListener("message", () => {
- arr.push(3);
- ws.close();
- assertEquals(arr, [1, 2, 3]);
- });
- ws.onmessage = () => arr.push(2);
- ws.onopen = () => ws.send("Echo");
- ws.onclose = () => {
- resolve();
- };
- await promise;
-});
-
-Deno.test("Close without frame", async () => {
- const { promise, resolve } = Promise.withResolvers<void>();
- const ws = new WebSocket("ws://localhost:4244");
- ws.onerror = () => fail();
- ws.onclose = (e) => {
- assertEquals(e.code, 1005);
- resolve();
- };
- await promise;
-});