Skip to content

Commit

Permalink
fix(websocket): bad rid on WebSocketStream abort(denoland#12913)
Browse files Browse the repository at this point in the history
Fix a bad resource ID error when aborting a WebSocketStream immediately
after its creation.
  • Loading branch information
Andreu Botella authored and bnoordhuis committed Nov 28, 2021
1 parent bfa2f30 commit b9d681d
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 9 deletions.
20 changes: 17 additions & 3 deletions cli/tests/testdata/websocketstream_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

import {
assertEquals,
assertRejects,
assertThrows,
assertThrowsAsync,
} from "../../../test_util/std/testing/asserts.ts";

Deno.test("fragment", () => {
Expand Down Expand Up @@ -57,12 +57,12 @@ Deno.test("echo string tls", async () => {
Deno.test("websocket error", async () => {
const ws = new WebSocketStream("wss://localhost:4242");
await Promise.all([
assertThrowsAsync(
assertRejects(
() => ws.connection,
Deno.errors.UnexpectedEof,
"tls handshake eof",
),
assertThrowsAsync(
assertRejects(
() => ws.closed,
Deno.errors.UnexpectedEof,
"tls handshake eof",
Expand All @@ -80,3 +80,17 @@ Deno.test("echo uint8array", async () => {
ws.close();
await ws.closed;
});

Deno.test("aborting immediately throws an AbortError", async () => {
const controller = new AbortController();
const wss = new WebSocketStream("ws://localhost:4242", {
signal: controller.signal,
});
controller.abort();
await assertRejects(
() => wss.connection,
DOMException,
"connection was aborted",
);
await assertRejects(() => wss.closed, DOMException, "connection was aborted");
});
18 changes: 12 additions & 6 deletions ext/websocket/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,16 @@ where
);
}

let cancel_resource = if let Some(cancel_rid) = args.cancel_handle {
let r = state
.borrow_mut()
.resource_table
.get::<WsCancelResource>(cancel_rid)?;
Some(r)
} else {
None
};

let unsafely_ignore_certificate_errors = state
.borrow()
.try_borrow::<UnsafelyIgnoreCertificateErrors>()
Expand Down Expand Up @@ -283,13 +293,9 @@ where

let client = client_async(request, socket);
let (stream, response): (WsStream, Response) =
if let Some(cancel_rid) = args.cancel_handle {
let r = state
.borrow_mut()
.resource_table
.get::<WsCancelResource>(cancel_rid)?;
if let Some(cancel_resource) = cancel_resource {
client
.or_cancel(r.0.to_owned())
.or_cancel(cancel_resource.0.to_owned())
.await
.map_err(|_| DomExceptionAbortError::new("connection was aborted"))?
} else {
Expand Down

0 comments on commit b9d681d

Please sign in to comment.