summaryrefslogtreecommitdiff
path: root/std/ws
diff options
context:
space:
mode:
Diffstat (limited to 'std/ws')
-rw-r--r--std/ws/mod.ts17
-rw-r--r--std/ws/test.ts225
2 files changed, 125 insertions, 117 deletions
diff --git a/std/ws/mod.ts b/std/ws/mod.ts
index 4d3f79f74..e2151a53e 100644
--- a/std/ws/mod.ts
+++ b/std/ws/mod.ts
@@ -1,5 +1,4 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-
import { decode, encode } from "../encoding/utf8.ts";
import { hasOwnProperty } from "../_util/has_own_property.ts";
import { BufReader, BufWriter } from "../io/bufio.ts";
@@ -10,8 +9,6 @@ import { TextProtoReader } from "../textproto/mod.ts";
import { Deferred, deferred } from "../async/deferred.ts";
import { assert } from "../_util/assert.ts";
import { concat } from "../bytes/mod.ts";
-import Conn = Deno.Conn;
-import Writer = Deno.Writer;
export enum OpCode {
Continue = 0x0,
@@ -66,7 +63,7 @@ export interface WebSocketFrame {
}
export interface WebSocket extends AsyncIterable<WebSocketEvent> {
- readonly conn: Conn;
+ readonly conn: Deno.Conn;
readonly isClosed: boolean;
[Symbol.asyncIterator](): AsyncIterableIterator<WebSocketEvent>;
@@ -108,7 +105,7 @@ export function unmask(payload: Uint8Array, mask?: Uint8Array): void {
/** Write websocket frame to given writer */
export async function writeFrame(
frame: WebSocketFrame,
- writer: Writer
+ writer: Deno.Writer
): Promise<void> {
const payloadLength = frame.payload.byteLength;
let header: Uint8Array;
@@ -200,7 +197,7 @@ function createMask(): Uint8Array {
}
class WebSocketImpl implements WebSocket {
- readonly conn: Conn;
+ readonly conn: Deno.Conn;
private readonly mask?: Uint8Array;
private readonly bufReader: BufReader;
private readonly bufWriter: BufWriter;
@@ -215,7 +212,7 @@ class WebSocketImpl implements WebSocket {
bufWriter,
mask,
}: {
- conn: Conn;
+ conn: Deno.Conn;
bufReader?: BufReader;
bufWriter?: BufWriter;
mask?: Uint8Array;
@@ -418,7 +415,7 @@ export function createSecAccept(nonce: string): string {
/** Upgrade given TCP connection into websocket connection */
export async function acceptWebSocket(req: {
- conn: Conn;
+ conn: Deno.Conn;
bufWriter: BufWriter;
bufReader: BufReader;
headers: Headers;
@@ -526,7 +523,7 @@ export async function connectWebSocket(
): Promise<WebSocket> {
const url = new URL(endpoint);
const { hostname } = url;
- let conn: Conn;
+ let conn: Deno.Conn;
if (url.protocol === "http:" || url.protocol === "ws:") {
const port = parseInt(url.port || "80");
conn = await Deno.connect({ hostname, port });
@@ -553,7 +550,7 @@ export async function connectWebSocket(
}
export function createWebSocket(params: {
- conn: Conn;
+ conn: Deno.Conn;
bufWriter?: BufWriter;
bufReader?: BufReader;
mask?: Uint8Array;
diff --git a/std/ws/test.ts b/std/ws/test.ts
index 9ef6ff94b..ad6b6256c 100644
--- a/std/ws/test.ts
+++ b/std/ws/test.ts
@@ -1,7 +1,6 @@
// 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";
-const { test } = Deno;
import { TextProtoReader } from "../textproto/mod.ts";
import * as bytes from "../bytes/mod.ts";
import {
@@ -17,29 +16,27 @@ import {
createWebSocket,
} from "./mod.ts";
import { encode, decode } from "../encoding/utf8.ts";
-import Writer = Deno.Writer;
-import Reader = Deno.Reader;
-import Conn = Deno.Conn;
-import Buffer = Deno.Buffer;
import { delay } from "../async/delay.ts";
-test("[ws] read unmasked text frame", async () => {
+Deno.test("[ws] read unmasked text frame", async () => {
// unmasked single text frame with payload "Hello"
const buf = new BufReader(
- new Buffer(new Uint8Array([0x81, 0x05, 0x48, 0x65, 0x6c, 0x6c, 0x6f]))
+ new Deno.Buffer(new Uint8Array([0x81, 0x05, 0x48, 0x65, 0x6c, 0x6c, 0x6f]))
);
const frame = await readFrame(buf);
assertEquals(frame.opcode, OpCode.TextFrame);
assertEquals(frame.mask, undefined);
- const actual = new TextDecoder().decode(new Buffer(frame.payload).bytes());
+ const actual = new TextDecoder().decode(
+ new Deno.Buffer(frame.payload).bytes()
+ );
assertEquals(actual, "Hello");
assertEquals(frame.isLastFrame, true);
});
-test("[ws] read masked text frame", async () => {
+Deno.test("[ws] read masked text frame", async () => {
// a masked single text frame with payload "Hello"
const buf = new BufReader(
- new Buffer(
+ new Deno.Buffer(
new Uint8Array([
0x81,
0x85,
@@ -58,59 +55,65 @@ test("[ws] read masked text frame", async () => {
const frame = await readFrame(buf);
assertEquals(frame.opcode, OpCode.TextFrame);
unmask(frame.payload, frame.mask);
- const actual = new TextDecoder().decode(new Buffer(frame.payload).bytes());
+ const actual = new TextDecoder().decode(
+ new Deno.Buffer(frame.payload).bytes()
+ );
assertEquals(actual, "Hello");
assertEquals(frame.isLastFrame, true);
});
-test("[ws] read unmasked split text frames", async () => {
+Deno.test("[ws] read unmasked split text frames", async () => {
const buf1 = new BufReader(
- new Buffer(new Uint8Array([0x01, 0x03, 0x48, 0x65, 0x6c]))
+ new Deno.Buffer(new Uint8Array([0x01, 0x03, 0x48, 0x65, 0x6c]))
);
const buf2 = new BufReader(
- new Buffer(new Uint8Array([0x80, 0x02, 0x6c, 0x6f]))
+ new Deno.Buffer(new Uint8Array([0x80, 0x02, 0x6c, 0x6f]))
);
const [f1, f2] = await Promise.all([readFrame(buf1), readFrame(buf2)]);
assertEquals(f1.isLastFrame, false);
assertEquals(f1.mask, undefined);
assertEquals(f1.opcode, OpCode.TextFrame);
- const actual1 = new TextDecoder().decode(new Buffer(f1.payload).bytes());
+ const actual1 = new TextDecoder().decode(new Deno.Buffer(f1.payload).bytes());
assertEquals(actual1, "Hel");
assertEquals(f2.isLastFrame, true);
assertEquals(f2.mask, undefined);
assertEquals(f2.opcode, OpCode.Continue);
- const actual2 = new TextDecoder().decode(new Buffer(f2.payload).bytes());
+ const actual2 = new TextDecoder().decode(new Deno.Buffer(f2.payload).bytes());
assertEquals(actual2, "lo");
});
-test("[ws] read unmasked ping / pong frame", async () => {
+Deno.test("[ws] read unmasked ping / pong frame", async () => {
// unmasked ping with payload "Hello"
const buf = new BufReader(
- new Buffer(new Uint8Array([0x89, 0x05, 0x48, 0x65, 0x6c, 0x6c, 0x6f]))
+ new Deno.Buffer(new Uint8Array([0x89, 0x05, 0x48, 0x65, 0x6c, 0x6c, 0x6f]))
);
const ping = await readFrame(buf);
assertEquals(ping.opcode, OpCode.Ping);
- const actual1 = new TextDecoder().decode(new Buffer(ping.payload).bytes());
+ const actual1 = new TextDecoder().decode(
+ new Deno.Buffer(ping.payload).bytes()
+ );
assertEquals(actual1, "Hello");
// prettier-ignore
const pongFrame= [0x8a, 0x85, 0x37, 0xfa, 0x21, 0x3d, 0x7f, 0x9f, 0x4d, 0x51, 0x58]
- const buf2 = new BufReader(new Buffer(new Uint8Array(pongFrame)));
+ const buf2 = new BufReader(new Deno.Buffer(new Uint8Array(pongFrame)));
const pong = await readFrame(buf2);
assertEquals(pong.opcode, OpCode.Pong);
assert(pong.mask !== undefined);
unmask(pong.payload, pong.mask);
- const actual2 = new TextDecoder().decode(new Buffer(pong.payload).bytes());
+ const actual2 = new TextDecoder().decode(
+ new Deno.Buffer(pong.payload).bytes()
+ );
assertEquals(actual2, "Hello");
});
-test("[ws] read unmasked big binary frame", async () => {
+Deno.test("[ws] read unmasked big binary frame", async () => {
const payloadLength = 0x100;
const a = [0x82, 0x7e, 0x01, 0x00];
for (let i = 0; i < payloadLength; i++) {
a.push(i);
}
- const buf = new BufReader(new Buffer(new Uint8Array(a)));
+ const buf = new BufReader(new Deno.Buffer(new Uint8Array(a)));
const bin = await readFrame(buf);
assertEquals(bin.opcode, OpCode.BinaryFrame);
assertEquals(bin.isLastFrame, true);
@@ -118,13 +121,13 @@ test("[ws] read unmasked big binary frame", async () => {
assertEquals(bin.payload.length, payloadLength);
});
-test("[ws] read unmasked bigger binary frame", async () => {
+Deno.test("[ws] read unmasked bigger binary frame", async () => {
const payloadLength = 0x10000;
const a = [0x82, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00];
for (let i = 0; i < payloadLength; i++) {
a.push(i);
}
- const buf = new BufReader(new Buffer(new Uint8Array(a)));
+ const buf = new BufReader(new Deno.Buffer(new Uint8Array(a)));
const bin = await readFrame(buf);
assertEquals(bin.opcode, OpCode.BinaryFrame);
assertEquals(bin.isLastFrame, true);
@@ -132,13 +135,13 @@ test("[ws] read unmasked bigger binary frame", async () => {
assertEquals(bin.payload.length, payloadLength);
});
-test("[ws] createSecAccept", () => {
+Deno.test("[ws] createSecAccept", () => {
const nonce = "dGhlIHNhbXBsZSBub25jZQ==";
const d = createSecAccept(nonce);
assertEquals(d, "s3pPLMBiTxaQ9kYGzzhZRbK+xOo=");
});
-test("[ws] acceptable", () => {
+Deno.test("[ws] acceptable", () => {
const ret = acceptable({
headers: new Headers({
upgrade: "websocket",
@@ -164,7 +167,7 @@ test("[ws] acceptable", () => {
);
});
-test("[ws] acceptable should return false when headers invalid", () => {
+Deno.test("[ws] acceptable should return false when headers invalid", () => {
assertEquals(
acceptable({
headers: new Headers({ "sec-websocket-key": "aaa" }),
@@ -191,20 +194,21 @@ test("[ws] acceptable should return false when headers invalid", () => {
);
});
-test("[ws] connectWebSocket should throw invalid scheme of url", async (): Promise<
- void
-> => {
- await assertThrowsAsync(
- async (): Promise<void> => {
- await connectWebSocket("file://hoge/hoge");
- }
- );
-});
+Deno.test(
+ "[ws] connectWebSocket should throw invalid scheme of url",
+ async (): Promise<void> => {
+ await assertThrowsAsync(
+ async (): Promise<void> => {
+ await connectWebSocket("file://hoge/hoge");
+ }
+ );
+ }
+);
-test("[ws] write and read masked frame", async () => {
+Deno.test("[ws] write and read masked frame", async () => {
const mask = new Uint8Array([0, 1, 2, 3]);
const msg = "hello";
- const buf = new Buffer();
+ const buf = new Deno.Buffer();
const r = new BufReader(buf);
await writeFrame(
{
@@ -223,9 +227,9 @@ test("[ws] write and read masked frame", async () => {
assertEquals(frame.payload, encode(msg));
});
-test("[ws] handshake should not send search when it's empty", async () => {
- const writer = new Buffer();
- const reader = new Buffer(encode("HTTP/1.1 400\r\n"));
+Deno.test("[ws] handshake should not send search when it's empty", async () => {
+ const writer = new Deno.Buffer();
+ const reader = new Deno.Buffer(encode("HTTP/1.1 400\r\n"));
await assertThrowsAsync(
async (): Promise<void> => {
@@ -244,31 +248,32 @@ test("[ws] handshake should not send search when it's empty", async () => {
assertEquals(statusLine, "GET / HTTP/1.1");
});
-test("[ws] handshake should send search correctly", async function wsHandshakeWithSearch(): Promise<
- void
-> {
- const writer = new Buffer();
- const reader = new Buffer(encode("HTTP/1.1 400\r\n"));
-
- await assertThrowsAsync(
- async (): Promise<void> => {
- await handshake(
- new URL("ws://example.com?a=1"),
- new Headers(),
- new BufReader(reader),
- new BufWriter(writer)
- );
- }
- );
+Deno.test(
+ "[ws] handshake should send search correctly",
+ async function wsHandshakeWithSearch(): Promise<void> {
+ const writer = new Deno.Buffer();
+ const reader = new Deno.Buffer(encode("HTTP/1.1 400\r\n"));
+
+ await assertThrowsAsync(
+ async (): Promise<void> => {
+ await handshake(
+ new URL("ws://example.com?a=1"),
+ new Headers(),
+ new BufReader(reader),
+ new BufWriter(writer)
+ );
+ }
+ );
- const tpReader = new TextProtoReader(new BufReader(writer));
- const statusLine = await tpReader.readLine();
+ const tpReader = new TextProtoReader(new BufReader(writer));
+ const statusLine = await tpReader.readLine();
- assertEquals(statusLine, "GET /?a=1 HTTP/1.1");
-});
+ assertEquals(statusLine, "GET /?a=1 HTTP/1.1");
+ }
+);
-test("[ws] ws.close() should use 1000 as close code", async () => {
- const buf = new Buffer();
+Deno.test("[ws] ws.close() should use 1000 as close code", async () => {
+ const buf = new Deno.Buffer();
const bufr = new BufReader(buf);
const conn = dummyConn(buf, buf);
const ws = createWebSocket({ conn });
@@ -279,7 +284,7 @@ test("[ws] ws.close() should use 1000 as close code", async () => {
assertEquals(code, 1000);
});
-function dummyConn(r: Reader, w: Writer): Conn {
+function dummyConn(r: Deno.Reader, w: Deno.Writer): Deno.Conn {
return {
rid: -1,
closeWrite: (): void => {},
@@ -291,7 +296,7 @@ function dummyConn(r: Reader, w: Writer): Conn {
};
}
-function delayedWriter(ms: number, dest: Writer): Writer {
+function delayedWriter(ms: number, dest: Deno.Writer): Deno.Writer {
return {
write(p: Uint8Array): Promise<number> {
return new Promise<number>((resolve) => {
@@ -302,11 +307,11 @@ function delayedWriter(ms: number, dest: Writer): Writer {
},
};
}
-test({
+Deno.test({
name: "[ws] WebSocket.send(), WebSocket.ping() should be exclusive",
fn: async (): Promise<void> => {
- const buf = new Buffer();
- const conn = dummyConn(new Buffer(), delayedWriter(1, buf));
+ const buf = new Deno.Buffer();
+ const conn = dummyConn(new Deno.Buffer(), delayedWriter(1, buf));
const sock = createWebSocket({ conn });
// Ensure send call
await Promise.all([
@@ -330,51 +335,57 @@ test({
},
});
-test("[ws] createSecKeyHasCorrectLength", () => {
+Deno.test("[ws] createSecKeyHasCorrectLength", () => {
// Note: relies on --seed=86 being passed to deno to reproduce failure in
// #4063.
const secKey = createSecKey();
assertEquals(atob(secKey).length, 16);
});
-test("[ws] WebSocket should throw `Deno.errors.ConnectionReset` when peer closed connection without close frame", async () => {
- const buf = new Buffer();
- const eofReader: Deno.Reader = {
- read(_: Uint8Array): Promise<number | null> {
- return Promise.resolve(null);
- },
- };
- const conn = dummyConn(eofReader, buf);
- const sock = createWebSocket({ conn });
- sock.closeForce();
- await assertThrowsAsync(
- () => sock.send("hello"),
- Deno.errors.ConnectionReset
- );
- await assertThrowsAsync(() => sock.ping(), Deno.errors.ConnectionReset);
- await assertThrowsAsync(() => sock.close(0), Deno.errors.ConnectionReset);
-});
-
-test("[ws] WebSocket shouldn't throw `Deno.errors.UnexpectedEof`", async () => {
- const buf = new Buffer();
- const eofReader: Deno.Reader = {
- read(_: Uint8Array): Promise<number | null> {
- return Promise.resolve(null);
- },
- };
- const conn = dummyConn(eofReader, buf);
- const sock = createWebSocket({ conn });
- const it = sock[Symbol.asyncIterator]();
- const { value, done } = await it.next();
- assertEquals(value, undefined);
- assertEquals(done, true);
-});
+Deno.test(
+ "[ws] WebSocket should throw `Deno.errors.ConnectionReset` when peer closed connection without close frame",
+ async () => {
+ const buf = new Deno.Buffer();
+ const eofReader: Deno.Reader = {
+ read(_: Uint8Array): Promise<number | null> {
+ return Promise.resolve(null);
+ },
+ };
+ const conn = dummyConn(eofReader, buf);
+ const sock = createWebSocket({ conn });
+ sock.closeForce();
+ await assertThrowsAsync(
+ () => sock.send("hello"),
+ Deno.errors.ConnectionReset
+ );
+ await assertThrowsAsync(() => sock.ping(), Deno.errors.ConnectionReset);
+ await assertThrowsAsync(() => sock.close(0), Deno.errors.ConnectionReset);
+ }
+);
+
+Deno.test(
+ "[ws] WebSocket shouldn't throw `Deno.errors.UnexpectedEof`",
+ async () => {
+ const buf = new Deno.Buffer();
+ const eofReader: Deno.Reader = {
+ read(_: Uint8Array): Promise<number | null> {
+ return Promise.resolve(null);
+ },
+ };
+ const conn = dummyConn(eofReader, buf);
+ const sock = createWebSocket({ conn });
+ const it = sock[Symbol.asyncIterator]();
+ const { value, done } = await it.next();
+ assertEquals(value, undefined);
+ assertEquals(done, true);
+ }
+);
-test({
+Deno.test({
name:
"[ws] WebSocket should reject sending promise when connection reset forcely",
fn: async () => {
- const buf = new Buffer();
+ const buf = new Deno.Buffer();
let timer: number | undefined;
const lazyWriter: Deno.Writer = {
write(_: Uint8Array): Promise<number> {
@@ -404,7 +415,7 @@ test({
},
});
-test("[ws] WebSocket should act as asyncIterator", async () => {
+Deno.test("[ws] WebSocket should act as asyncIterator", async () => {
const pingHello = new Uint8Array([0x89, 0x05, 0x48, 0x65, 0x6c, 0x6c, 0x6f]);
const hello = new Uint8Array([0x81, 0x05, 0x48, 0x65, 0x6c, 0x6c, 0x6f]);
const close = new Uint8Array([0x88, 0x04, 0x03, 0xf3, 0x34, 0x32]);
@@ -418,7 +429,7 @@ test("[ws] WebSocket should act as asyncIterator", async () => {
let frame = Frames.ping;
- const reader: Reader = {
+ const reader: Deno.Reader = {
read(p: Uint8Array): Promise<number | null> {
if (frame === Frames.ping) {
frame = Frames.hello;
@@ -442,7 +453,7 @@ test("[ws] WebSocket should act as asyncIterator", async () => {
},
};
- const conn = dummyConn(reader, new Buffer());
+ const conn = dummyConn(reader, new Deno.Buffer());
const sock = createWebSocket({ conn });
const events = [];