mirror of
https://github.com/denoland/deno.git
synced 2025-03-09 13:49:37 -04:00
fix(ext/websocket): WebSocket dispatch single close event (#13443)
This commit is contained in:
parent
bcc8891ec3
commit
50ebb8799b
5 changed files with 62 additions and 39 deletions
|
@ -738,10 +738,12 @@ fn websocket_server_multi_field_connection_header() {
|
||||||
.uri("ws://localhost:4319")
|
.uri("ws://localhost:4319")
|
||||||
.body(())
|
.body(())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert!(
|
let (mut socket, _) =
|
||||||
deno_runtime::deno_websocket::tokio_tungstenite::tungstenite::connect(req)
|
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());
|
assert!(child.wait().unwrap().success());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -357,32 +357,18 @@
|
||||||
|
|
||||||
httpConn.close();
|
httpConn.close();
|
||||||
|
|
||||||
if (ws[_readyState] === WebSocket.CLOSING) {
|
ws[_readyState] = WebSocket.OPEN;
|
||||||
await core.opAsync("op_ws_close", wsRid);
|
const event = new Event("open");
|
||||||
|
ws.dispatchEvent(event);
|
||||||
|
|
||||||
ws[_readyState] = WebSocket.CLOSED;
|
ws[_eventLoop]();
|
||||||
|
if (ws[_idleTimeoutDuration]) {
|
||||||
const errEvent = new ErrorEvent("error");
|
ws.addEventListener(
|
||||||
ws.dispatchEvent(errEvent);
|
"close",
|
||||||
|
() => clearTimeout(ws[_idleTimeoutTimeout]),
|
||||||
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[_serverHandleIdleTimeout]();
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
if (SetPrototypeDelete(httpConn.managedResources, streamRid)) {
|
if (SetPrototypeDelete(httpConn.managedResources, streamRid)) {
|
||||||
|
|
|
@ -29,6 +29,8 @@
|
||||||
StringPrototypeToLowerCase,
|
StringPrototypeToLowerCase,
|
||||||
Symbol,
|
Symbol,
|
||||||
SymbolIterator,
|
SymbolIterator,
|
||||||
|
PromisePrototypeCatch,
|
||||||
|
SymbolFor,
|
||||||
} = window.__bootstrap.primordials;
|
} = window.__bootstrap.primordials;
|
||||||
|
|
||||||
webidl.converters["sequence<DOMString> or DOMString"] = (V, opts) => {
|
webidl.converters["sequence<DOMString> or DOMString"] = (V, opts) => {
|
||||||
|
@ -367,16 +369,19 @@
|
||||||
} else if (this[_readyState] === OPEN) {
|
} else if (this[_readyState] === OPEN) {
|
||||||
this[_readyState] = CLOSING;
|
this[_readyState] = CLOSING;
|
||||||
|
|
||||||
PromisePrototypeThen(
|
PromisePrototypeCatch(
|
||||||
core.opAsync("op_ws_close", this[_rid], code, reason),
|
core.opAsync("op_ws_close", this[_rid], code, reason),
|
||||||
() => {
|
(err) => {
|
||||||
this[_readyState] = CLOSED;
|
this[_readyState] = CLOSED;
|
||||||
const event = new CloseEvent("close", {
|
|
||||||
wasClean: true,
|
const errorEv = new ErrorEvent("error", {
|
||||||
code: code ?? 1005,
|
error: err,
|
||||||
reason,
|
message: ErrorPrototypeToString(err),
|
||||||
});
|
});
|
||||||
this.dispatchEvent(event);
|
this.dispatchEvent(errorEv);
|
||||||
|
|
||||||
|
const closeEv = new CloseEvent("close");
|
||||||
|
this.dispatchEvent(closeEv);
|
||||||
core.tryClose(this[_rid]);
|
core.tryClose(this[_rid]);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -384,7 +389,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
async [_eventLoop]() {
|
async [_eventLoop]() {
|
||||||
while (this[_readyState] === OPEN) {
|
while (this[_readyState] !== CLOSED) {
|
||||||
const { kind, value } = await core.opAsync(
|
const { kind, value } = await core.opAsync(
|
||||||
"op_ws_next_event",
|
"op_ws_next_event",
|
||||||
this[_rid],
|
this[_rid],
|
||||||
|
@ -429,9 +434,23 @@
|
||||||
}
|
}
|
||||||
case "closed":
|
case "closed":
|
||||||
case "close": {
|
case "close": {
|
||||||
|
const prevState = this[_readyState];
|
||||||
this[_readyState] = CLOSED;
|
this[_readyState] = CLOSED;
|
||||||
clearTimeout(this[_idleTimeoutTimeout]);
|
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", {
|
const event = new CloseEvent("close", {
|
||||||
wasClean: true,
|
wasClean: true,
|
||||||
code: value.code,
|
code: value.code,
|
||||||
|
@ -487,6 +506,19 @@
|
||||||
}, (this[_idleTimeoutDuration] / 2) * 1000);
|
}, (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, {
|
ObjectDefineProperties(WebSocket, {
|
||||||
|
|
|
@ -136,6 +136,9 @@ impl WsStreamResource {
|
||||||
match res {
|
match res {
|
||||||
Ok(()) => Ok(()),
|
Ok(()) => Ok(()),
|
||||||
Err(Error::ConnectionClosed) => Ok(()),
|
Err(Error::ConnectionClosed) => Ok(()),
|
||||||
|
Err(tokio_tungstenite::tungstenite::Error::Protocol(
|
||||||
|
tokio_tungstenite::tungstenite::error::ProtocolError::SendAfterClosing,
|
||||||
|
)) => Ok(()),
|
||||||
Err(err) => Err(err.into()),
|
Err(err) => Err(err.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4184,12 +4184,12 @@
|
||||||
"eventhandlers.any.worker.html?wss": true,
|
"eventhandlers.any.worker.html?wss": true,
|
||||||
"referrer.any.html": true,
|
"referrer.any.html": true,
|
||||||
"referrer.any.worker.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?wpt_flags=h2": false,
|
||||||
"Close-delayed.any.html?wss": false,
|
"Close-delayed.any.html?wss": true,
|
||||||
"Close-delayed.any.worker.html": false,
|
"Close-delayed.any.worker.html": true,
|
||||||
"Close-delayed.any.worker.html?wpt_flags=h2": false,
|
"Close-delayed.any.worker.html?wpt_flags=h2": false,
|
||||||
"Close-delayed.any.worker.html?wss": false,
|
"Close-delayed.any.worker.html?wss": true,
|
||||||
"stream": {
|
"stream": {
|
||||||
"tentative": {
|
"tentative": {
|
||||||
"abort.any.html?wss": true,
|
"abort.any.html?wss": true,
|
||||||
|
|
Loading…
Add table
Reference in a new issue