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

fix(ext/websocket): WebSocket dispatch single close event (#13443)

This commit is contained in:
Leo Kettmeir 2022-05-23 13:21:11 +02:00 committed by GitHub
parent d55444b41c
commit 3c97bbe165
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 62 additions and 39 deletions

View file

@ -738,10 +738,12 @@ fn websocket_server_multi_field_connection_header() {
.uri("ws://localhost:4319")
.body(())
.unwrap();
assert!(
let (mut socket, _) =
deno_runtime::deno_websocket::tokio_tungstenite::tungstenite::connect(req)
.is_ok()
);
.unwrap();
let message = socket.read_message().unwrap();
assert_eq!(message, deno_runtime::deno_websocket::tokio_tungstenite::tungstenite::Message::Close(None));
socket.close(None).unwrap();
assert!(child.wait().unwrap().success());
}

View file

@ -357,32 +357,18 @@
httpConn.close();
if (ws[_readyState] === WebSocket.CLOSING) {
await core.opAsync("op_ws_close", wsRid);
ws[_readyState] = WebSocket.OPEN;
const event = new Event("open");
ws.dispatchEvent(event);
ws[_readyState] = WebSocket.CLOSED;
const errEvent = new ErrorEvent("error");
ws.dispatchEvent(errEvent);
const event = new CloseEvent("close");
ws.dispatchEvent(event);
core.tryClose(wsRid);
} else {
ws[_readyState] = WebSocket.OPEN;
const event = new Event("open");
ws.dispatchEvent(event);
ws[_eventLoop]();
if (ws[_idleTimeoutDuration]) {
ws.addEventListener(
"close",
() => clearTimeout(ws[_idleTimeoutTimeout]),
);
}
ws[_serverHandleIdleTimeout]();
ws[_eventLoop]();
if (ws[_idleTimeoutDuration]) {
ws.addEventListener(
"close",
() => clearTimeout(ws[_idleTimeoutTimeout]),
);
}
ws[_serverHandleIdleTimeout]();
}
} finally {
if (SetPrototypeDelete(httpConn.managedResources, streamRid)) {

View file

@ -29,6 +29,8 @@
StringPrototypeToLowerCase,
Symbol,
SymbolIterator,
PromisePrototypeCatch,
SymbolFor,
} = window.__bootstrap.primordials;
webidl.converters["sequence<DOMString> or DOMString"] = (V, opts) => {
@ -367,16 +369,19 @@
} else if (this[_readyState] === OPEN) {
this[_readyState] = CLOSING;
PromisePrototypeThen(
PromisePrototypeCatch(
core.opAsync("op_ws_close", this[_rid], code, reason),
() => {
(err) => {
this[_readyState] = CLOSED;
const event = new CloseEvent("close", {
wasClean: true,
code: code ?? 1005,
reason,
const errorEv = new ErrorEvent("error", {
error: err,
message: ErrorPrototypeToString(err),
});
this.dispatchEvent(event);
this.dispatchEvent(errorEv);
const closeEv = new CloseEvent("close");
this.dispatchEvent(closeEv);
core.tryClose(this[_rid]);
},
);
@ -384,7 +389,7 @@
}
async [_eventLoop]() {
while (this[_readyState] === OPEN) {
while (this[_readyState] !== CLOSED) {
const { kind, value } = await core.opAsync(
"op_ws_next_event",
this[_rid],
@ -429,9 +434,23 @@
}
case "closed":
case "close": {
const prevState = this[_readyState];
this[_readyState] = CLOSED;
clearTimeout(this[_idleTimeoutTimeout]);
if (prevState === OPEN) {
try {
await core.opAsync(
"op_ws_close",
this[_rid],
value.code,
value.reason,
);
} catch {
// ignore failures
}
}
const event = new CloseEvent("close", {
wasClean: true,
code: value.code,
@ -487,6 +506,19 @@
}, (this[_idleTimeoutDuration] / 2) * 1000);
}
}
[SymbolFor("Deno.customInspect")](inspect) {
return `${this.constructor.name} ${
inspect({
url: this.url,
readyState: this.readyState,
extensions: this.extensions,
protocol: this.protocol,
binaryType: this.binaryType,
bufferedAmount: this.bufferedAmount,
})
}`;
}
}
ObjectDefineProperties(WebSocket, {

View file

@ -136,6 +136,9 @@ impl WsStreamResource {
match res {
Ok(()) => Ok(()),
Err(Error::ConnectionClosed) => Ok(()),
Err(tokio_tungstenite::tungstenite::Error::Protocol(
tokio_tungstenite::tungstenite::error::ProtocolError::SendAfterClosing,
)) => Ok(()),
Err(err) => Err(err.into()),
}
}

View file

@ -4184,12 +4184,12 @@
"eventhandlers.any.worker.html?wss": true,
"referrer.any.html": true,
"referrer.any.worker.html": true,
"Close-delayed.any.html": false,
"Close-delayed.any.html": true,
"Close-delayed.any.html?wpt_flags=h2": false,
"Close-delayed.any.html?wss": false,
"Close-delayed.any.worker.html": false,
"Close-delayed.any.html?wss": true,
"Close-delayed.any.worker.html": true,
"Close-delayed.any.worker.html?wpt_flags=h2": false,
"Close-delayed.any.worker.html?wss": false,
"Close-delayed.any.worker.html?wss": true,
"stream": {
"tentative": {
"abort.any.html?wss": true,