1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-22 23:34:47 -05:00

fix: parse websocket messages correctly (#10318)

This commit is contained in:
Luca Casonato 2021-04-23 01:31:34 +02:00 committed by GitHub
parent 21ab4d94c0
commit 2b5cc6b498
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 57 additions and 46 deletions

View file

@ -307,60 +307,71 @@
async #eventLoop() {
while (this.#readyState === OPEN) {
const message = await core.opAsync(
const { kind, value } = await core.opAsync(
"op_ws_next_event",
this.#rid,
);
if ("string" in message) {
const event = new MessageEvent("message", {
data: message.string,
origin: this.#url,
});
event.target = this;
this.dispatchEvent(event);
} else if ("binary" in message) {
let data;
if (this.binaryType === "blob") {
data = new Blob([new Uint8Array(message.binary)]);
} else {
data = new Uint8Array(message.binary).buffer;
switch (kind) {
case "string": {
const event = new MessageEvent("message", {
data: value,
origin: this.#url,
});
event.target = this;
this.dispatchEvent(event);
break;
}
case "binary": {
let data;
const event = new MessageEvent("message", {
data,
origin: this.#url,
});
event.target = this;
this.dispatchEvent(event);
} else if ("ping" in message) {
core.opAsync("op_ws_send", {
rid: this.#rid,
kind: "pong",
});
} else if ("close" in message) {
this.#readyState = CLOSED;
if (this.binaryType === "blob") {
data = new Blob([new Uint8Array(value)]);
} else {
data = new Uint8Array(value).buffer;
}
const event = new CloseEvent("close", {
wasClean: true,
code: message.close.code,
reason: message.close.reason,
});
event.target = this;
this.dispatchEvent(event);
tryClose(this.#rid);
} else if ("error" in message) {
this.#readyState = CLOSED;
const event = new MessageEvent("message", {
data,
origin: this.#url,
});
event.target = this;
this.dispatchEvent(event);
break;
}
case "ping": {
core.opAsync("op_ws_send", {
rid: this.#rid,
kind: "pong",
});
break;
}
case "close": {
this.#readyState = CLOSED;
const errorEv = new ErrorEvent("error");
errorEv.target = this;
this.dispatchEvent(errorEv);
const event = new CloseEvent("close", {
wasClean: true,
code: value.code,
reason: value.reason,
});
event.target = this;
this.dispatchEvent(event);
tryClose(this.#rid);
break;
}
case "error": {
this.#readyState = CLOSED;
const closeEv = new CloseEvent("close");
closeEv.target = this;
this.dispatchEvent(closeEv);
tryClose(this.#rid);
const errorEv = new ErrorEvent("error");
errorEv.target = this;
this.dispatchEvent(errorEv);
const closeEv = new CloseEvent("close");
closeEv.target = this;
this.dispatchEvent(closeEv);
tryClose(this.#rid);
break;
}
}
}
}

View file

@ -282,7 +282,7 @@ pub async fn op_ws_close(
}
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
#[serde(tag = "kind", content = "value", rename_all = "camelCase")]
pub enum NextEventResponse {
String(String),
Binary(Vec<u8>),