1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-25 15:29:32 -05:00

fix(ext/websocket): upgrade fastwebsockets to 0.2.4 (#18791)

Fixes https://github.com/denoland/deno/issues/18775
This commit is contained in:
Divy Srivastava 2023-04-21 12:25:02 +05:30 committed by GitHub
parent 1976504c63
commit 4e944dea1d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 70 additions and 5 deletions

4
Cargo.lock generated
View file

@ -1819,9 +1819,9 @@ dependencies = [
[[package]] [[package]]
name = "fastwebsockets" name = "fastwebsockets"
version = "0.2.1" version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99a248d92ac4e9048a30d147d7897eaaadd0a5230f11982ab7d6935d7d268902" checksum = "fcf2f933f24f45831bd66580a8f9394e440f1f5a23806cf0d4d8b6649e1a01e9"
dependencies = [ dependencies = [
"base64 0.21.0", "base64 0.21.0",
"cc", "cc",

View file

@ -1,5 +1,11 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
import { assertEquals, assertThrows, deferred, fail } from "./test_util.ts"; import {
assert,
assertEquals,
assertThrows,
deferred,
fail,
} from "./test_util.ts";
Deno.test({ permissions: "none" }, function websocketPermissionless() { Deno.test({ permissions: "none" }, function websocketPermissionless() {
assertThrows( assertThrows(
@ -82,3 +88,46 @@ Deno.test(
ws.close(); ws.close();
}, },
); );
// https://github.com/denoland/deno/issues/18775
Deno.test({
sanitizeOps: false,
sanitizeResources: false,
}, async function websocketDoubleClose() {
const promise = deferred();
const ac = new AbortController();
const listeningPromise = deferred();
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: () => listeningPromise.resolve(),
hostname: "localhost",
port: 4247,
});
await listeningPromise;
const ws = new WebSocket("ws://localhost:4247/");
assertEquals(ws.url, "ws://localhost:4247/");
ws.onerror = () => fail();
ws.onmessage = () => ws.send("bye");
ws.onclose = () => {
promise.resolve();
};
await Promise.all([promise, server]);
});

View file

@ -16,7 +16,7 @@ path = "lib.rs"
[dependencies] [dependencies]
deno_core.workspace = true deno_core.workspace = true
deno_tls.workspace = true deno_tls.workspace = true
fastwebsockets = { version = "0.2.1", features = ["upgrade"] } fastwebsockets = { version = "0.2.4", features = ["upgrade"] }
http.workspace = true http.workspace = true
hyper.workspace = true hyper.workspace = true
serde.workspace = true serde.workspace = true

View file

@ -34,6 +34,7 @@ use std::cell::Cell;
use std::cell::RefCell; use std::cell::RefCell;
use std::convert::TryFrom; use std::convert::TryFrom;
use std::fmt; use std::fmt;
use std::future::Future;
use std::path::PathBuf; use std::path::PathBuf;
use std::rc::Rc; use std::rc::Rc;
use std::sync::Arc; use std::sync::Arc;
@ -239,7 +240,8 @@ where
_ => unreachable!(), _ => unreachable!(),
}; };
let client = fastwebsockets::handshake::client(request, socket); let client =
fastwebsockets::handshake::client(&LocalExecutor, request, socket);
let (stream, response): (WebSocket<Upgraded>, Response<Body>) = let (stream, response): (WebSocket<Upgraded>, Response<Body>) =
if let Some(cancel_resource) = cancel_resource { if let Some(cancel_resource) = cancel_resource {
@ -533,3 +535,17 @@ pub fn get_network_error_class_name(e: &AnyError) -> Option<&'static str> {
e.downcast_ref::<DomExceptionNetworkError>() e.downcast_ref::<DomExceptionNetworkError>()
.map(|_| "DOMExceptionNetworkError") .map(|_| "DOMExceptionNetworkError")
} }
// Needed so hyper can use non Send futures
#[derive(Clone)]
struct LocalExecutor;
impl<Fut> hyper::rt::Executor<Fut> for LocalExecutor
where
Fut: Future + 'static,
Fut::Output: 'static,
{
fn execute(&self, fut: Fut) {
tokio::task::spawn_local(fut);
}
}