From ed20bda6ec324b8143c6210024647d2692232c26 Mon Sep 17 00:00:00 2001 From: Yusuke Sakurai Date: Mon, 11 Feb 2019 08:45:24 +0900 Subject: refactor: make acceptWebSocket independent from ServerRequest (denoland/deno_std#178) Original: https://github.com/denoland/deno_std/commit/88ddd5677dec9a8281c4d86ba27b0c9047189740 --- ws/mod.ts | 20 +++++++++++++------- ws/test.ts | 37 ++++++++++++++++++++++++++++++++++--- 2 files changed, 47 insertions(+), 10 deletions(-) (limited to 'ws') diff --git a/ws/mod.ts b/ws/mod.ts index ca47bf5b8..6433a75d1 100644 --- a/ws/mod.ts +++ b/ws/mod.ts @@ -1,9 +1,9 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. import { Buffer, Writer, Conn } from "deno"; -import { ServerRequest } from "../http/server.ts"; import { BufReader, BufWriter } from "../io/bufio.ts"; import { readLong, readShort, sliceLongToBytes } from "../io/ioutil.ts"; import { Sha1 } from "./sha1.ts"; +import { writeResponse } from "../http/server.ts"; export enum OpCode { Continue = 0x0, @@ -71,6 +71,7 @@ export type WebSocket = { class WebSocketImpl implements WebSocket { encoder = new TextEncoder(); + constructor(private conn: Conn, private mask?: Uint8Array) {} async *receive(): AsyncIterableIterator { @@ -278,19 +279,24 @@ export function unmask(payload: Uint8Array, mask?: Uint8Array) { } } -export function acceptable(req: ServerRequest): boolean { +export function acceptable(req: { headers: Headers }): boolean { return ( req.headers.get("upgrade") === "websocket" && - req.headers.has("sec-websocket-key") + req.headers.has("sec-websocket-key") && + req.headers.get("sec-websocket-key").length > 0 ); } -export async function acceptWebSocket(req: ServerRequest): Promise { +export async function acceptWebSocket(req: { + conn: Conn; + headers: Headers; +}): Promise { + const { conn, headers } = req; if (acceptable(req)) { - const sock = new WebSocketImpl(req.conn); - const secKey = req.headers.get("sec-websocket-key"); + const sock = new WebSocketImpl(conn); + const secKey = headers.get("sec-websocket-key"); const secAccept = createSecAccept(secKey); - await req.respond({ + await writeResponse(conn, { status: 101, headers: new Headers({ Upgrade: "websocket", diff --git a/ws/test.ts b/ws/test.ts index 6a78d9fe0..684c43002 100644 --- a/ws/test.ts +++ b/ws/test.ts @@ -3,9 +3,14 @@ import "./sha1_test.ts"; import { Buffer } from "deno"; import { BufReader } from "../io/bufio.ts"; -import { test, assert, assertEqual } from "../testing/mod.ts"; -import { createSecAccept, OpCode, readFrame, unmask } from "./mod.ts"; -import { serve } from "../http/server.ts"; +import { assert, assertEqual, test } from "../testing/mod.ts"; +import { + acceptable, + createSecAccept, + OpCode, + readFrame, + unmask +} from "./mod.ts"; test(async function testReadUnmaskedTextFrame() { // unmasked single text frame with payload "Hello" @@ -129,3 +134,29 @@ test(async function testCreateSecAccept() { const d = createSecAccept(nonce); assertEqual(d, "s3pPLMBiTxaQ9kYGzzhZRbK+xOo="); }); + +test(function testAcceptable() { + const ret = acceptable({ + headers: new Headers({ + upgrade: "websocket", + "sec-websocket-key": "aaa" + }) + }); + assertEqual(ret, true); +}); + +const invalidHeaders = [ + { "sec-websocket-key": "aaa" }, + { upgrade: "websocket" }, + { upgrade: "invalid", "sec-websocket-key": "aaa" }, + { upgrade: "websocket", "sec-websocket-ky": "" } +]; + +test(function testAcceptableInvalid() { + for (const pat of invalidHeaders) { + const ret = acceptable({ + headers: new Headers(pat) + }); + assertEqual(ret, false); + } +}); -- cgit v1.2.3