diff options
author | Leo Kettmeir <crowlkats@toaxl.com> | 2022-05-23 13:21:11 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-05-23 13:21:11 +0200 |
commit | 3c97bbe165ef0c5e4fa9b9eb637ff481d8c86884 (patch) | |
tree | 750c15354bda8c535cdc4db95d26b19e01ed848d /ext/websocket/01_websocket.js | |
parent | d55444b41cdee5b3f281896a7e60ff06c5fc01de (diff) |
fix(ext/websocket): WebSocket dispatch single close event (#13443)
Diffstat (limited to 'ext/websocket/01_websocket.js')
-rw-r--r-- | ext/websocket/01_websocket.js | 48 |
1 files changed, 40 insertions, 8 deletions
diff --git a/ext/websocket/01_websocket.js b/ext/websocket/01_websocket.js index 19c5e2875..3585256fc 100644 --- a/ext/websocket/01_websocket.js +++ b/ext/websocket/01_websocket.js @@ -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, { |