summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--extensions/webidl/00_webidl.js4
-rw-r--r--extensions/websocket/01_websocket.js322
-rw-r--r--tools/wpt/config.json7
-rw-r--r--tools/wpt/expectation.json185
4 files changed, 401 insertions, 117 deletions
diff --git a/extensions/webidl/00_webidl.js b/extensions/webidl/00_webidl.js
index e6cda92d4..87e9eccb7 100644
--- a/extensions/webidl/00_webidl.js
+++ b/extensions/webidl/00_webidl.js
@@ -579,6 +579,10 @@
converters.ByteString,
);
+ converters["sequence<DOMString>"] = createSequenceConverter(
+ converters.DOMString,
+ );
+
function requiredArguments(length, required, opts = {}) {
if (length < required) {
const errMsg = `${
diff --git a/extensions/websocket/01_websocket.js b/extensions/websocket/01_websocket.js
index 3c3e12f83..225c6725b 100644
--- a/extensions/websocket/01_websocket.js
+++ b/extensions/websocket/01_websocket.js
@@ -3,28 +3,41 @@
((window) => {
const core = window.Deno.core;
-
- // provided by "deno_web"
const { URL } = window.__bootstrap.url;
+ const webidl = window.__bootstrap.webidl;
+ const { HTTP_TOKEN_CODE_POINT_RE } = window.__bootstrap.infra;
+
+ webidl.converters["sequence<DOMString> or DOMString"] = (V, opts) => {
+ // Union for (sequence<DOMString> or DOMString)
+ if (webidl.type(V) === "Object" && V !== null) {
+ if (V[Symbol.iterator] !== undefined) {
+ return webidl.converters["sequence<DOMString>"](V, opts);
+ }
+ }
+ return webidl.converters.DOMString(V, opts);
+ };
+
+ webidl.converters["WebSocketSend"] = (V, opts) => {
+ // Union for (Blob or ArrayBufferView or ArrayBuffer or USVString)
+ if (V instanceof Blob) {
+ return webidl.converters["Blob"](V, opts);
+ }
+ if (typeof V === "object") {
+ if (V instanceof ArrayBuffer || V instanceof SharedArrayBuffer) {
+ return webidl.converters["ArrayBuffer"](V, opts);
+ }
+ if (ArrayBuffer.isView(V)) {
+ return webidl.converters["ArrayBufferView"](V, opts);
+ }
+ }
+ return webidl.converters["USVString"](V, opts);
+ };
const CONNECTING = 0;
const OPEN = 1;
const CLOSING = 2;
const CLOSED = 3;
- function requiredArguments(
- name,
- length,
- required,
- ) {
- if (length < required) {
- const errMsg = `${name} requires at least ${required} argument${
- required === 1 ? "" : "s"
- }, but only ${length} present`;
- throw new TypeError(errMsg);
- }
- }
-
/**
* Tries to close the resource (and ignores BadResource errors).
* @param {number} rid
@@ -74,14 +87,104 @@
});
}
+ const _readyState = Symbol("[[readyState]]");
+ const _url = Symbol("[[url]]");
+ const _rid = Symbol("[[rid]]");
+ const _extensions = Symbol("[[extensions]]");
+ const _protocol = Symbol("[[protocol]]");
+ const _binaryType = Symbol("[[binaryType]]");
+ const _bufferedAmount = Symbol("[[bufferedAmount]]");
class WebSocket extends EventTarget {
- #readyState = CONNECTING;
+ [_rid];
+
+ [_readyState] = CONNECTING;
+ get readyState() {
+ webidl.assertBranded(this, WebSocket);
+ return this[_readyState];
+ }
+
+ get CONNECTING() {
+ webidl.assertBranded(this, WebSocket);
+ return CONNECTING;
+ }
+ get OPEN() {
+ webidl.assertBranded(this, WebSocket);
+ return OPEN;
+ }
+ get CLOSING() {
+ webidl.assertBranded(this, WebSocket);
+ return CLOSING;
+ }
+ get CLOSED() {
+ webidl.assertBranded(this, WebSocket);
+ return CLOSED;
+ }
+
+ [_extensions] = "";
+ get extensions() {
+ webidl.assertBranded(this, WebSocket);
+ return this[_extensions];
+ }
+
+ [_protocol] = "";
+ get protocol() {
+ webidl.assertBranded(this, WebSocket);
+ return this[_protocol];
+ }
+
+ [_url] = "";
+ get url() {
+ webidl.assertBranded(this, WebSocket);
+ return this[_url];
+ }
+
+ [_binaryType] = "blob";
+ get binaryType() {
+ webidl.assertBranded(this, WebSocket);
+ return this[_binaryType];
+ }
+ set binaryType(value) {
+ webidl.assertBranded(this, WebSocket);
+ value = webidl.converters.DOMString(value, {
+ prefix: "Failed to set 'binaryType' on 'WebSocket'",
+ });
+ if (value === "blob" || value === "arraybuffer") {
+ this[_binaryType] = value;
+ }
+ }
+
+ [_bufferedAmount] = 0;
+ get bufferedAmount() {
+ webidl.assertBranded(this, WebSocket);
+ return this[_bufferedAmount];
+ }
constructor(url, protocols = []) {
super();
- requiredArguments("WebSocket", arguments.length, 1);
-
- const wsURL = new URL(url);
+ this[webidl.brand] = webidl.brand;
+ const prefix = "Failed to construct 'WebSocket'";
+ webidl.requiredArguments(arguments.length, 1, {
+ prefix,
+ });
+ url = webidl.converters.USVString(url, {
+ prefix,
+ context: "Argument 1",
+ });
+ protocols = webidl.converters["sequence<DOMString> or DOMString"](
+ protocols,
+ {
+ prefix,
+ context: "Argument 2",
+ },
+ );
+
+ let wsURL;
+
+ try {
+ wsURL = new URL(url);
+ } catch (e) {
+ throw new DOMException(e.message, "SyntaxError");
+ }
if (wsURL.protocol !== "ws:" && wsURL.protocol !== "wss:") {
throw new DOMException(
@@ -97,16 +200,16 @@
);
}
- this.#url = wsURL.href;
+ this[_url] = wsURL.href;
- core.opSync("op_ws_check_permission", this.#url);
+ core.opSync("op_ws_check_permission", this[_url]);
- if (protocols && typeof protocols === "string") {
+ if (typeof protocols === "string") {
protocols = [protocols];
}
if (
- protocols.some((x) => protocols.indexOf(x) !== protocols.lastIndexOf(x))
+ protocols.length !== new Set(protocols.map((p) => p.toLowerCase())).size
) {
throw new DOMException(
"Can't supply multiple times the same protocol.",
@@ -114,19 +217,28 @@
);
}
+ if (
+ protocols.some((protocol) => !HTTP_TOKEN_CODE_POINT_RE.test(protocol))
+ ) {
+ throw new DOMException(
+ "Invalid protocol value.",
+ "SyntaxError",
+ );
+ }
+
core.opAsync("op_ws_create", {
url: wsURL.href,
protocols: protocols.join(", "),
}).then((create) => {
- this.#rid = create.rid;
- this.#extensions = create.extensions;
- this.#protocol = create.protocol;
+ this[_rid] = create.rid;
+ this[_extensions] = create.extensions;
+ this[_protocol] = create.protocol;
- if (this.#readyState === CLOSING) {
+ if (this[_readyState] === CLOSING) {
core.opAsync("op_ws_close", {
- rid: this.#rid,
+ rid: this[_rid],
}).then(() => {
- this.#readyState = CLOSED;
+ this[_readyState] = CLOSED;
const errEvent = new ErrorEvent("error");
errEvent.target = this;
@@ -135,10 +247,10 @@
const event = new CloseEvent("close");
event.target = this;
this.dispatchEvent(event);
- tryClose(this.#rid);
+ tryClose(this[_rid]);
});
} else {
- this.#readyState = OPEN;
+ this[_readyState] = OPEN;
const event = new Event("open");
event.target = this;
this.dispatchEvent(event);
@@ -146,7 +258,7 @@
this.#eventLoop();
}
}).catch((err) => {
- this.#readyState = CLOSED;
+ this[_readyState] = CLOSED;
const errorEv = new ErrorEvent(
"error",
@@ -161,67 +273,29 @@
});
}
- get CONNECTING() {
- return CONNECTING;
- }
- get OPEN() {
- return OPEN;
- }
- get CLOSING() {
- return CLOSING;
- }
- get CLOSED() {
- return CLOSED;
- }
-
- get readyState() {
- return this.#readyState;
- }
-
- #extensions = "";
- #protocol = "";
- #url = "";
- #rid;
-
- get extensions() {
- return this.#extensions;
- }
- get protocol() {
- return this.#protocol;
- }
-
- #binaryType = "blob";
- get binaryType() {
- return this.#binaryType;
- }
- set binaryType(value) {
- if (value === "blob" || value === "arraybuffer") {
- this.#binaryType = value;
- }
- }
- #bufferedAmount = 0;
- get bufferedAmount() {
- return this.#bufferedAmount;
- }
-
- get url() {
- return this.#url;
- }
-
send(data) {
- requiredArguments("WebSocket.send", arguments.length, 1);
+ webidl.assertBranded(this, WebSocket);
+ const prefix = "Failed to execute 'send' on 'WebSocket'";
+
+ webidl.requiredArguments(arguments.length, 1, {
+ prefix,
+ });
+ data = webidl.converters.WebSocketSend(data, {
+ prefix,
+ context: "Argument 1",
+ });
- if (this.#readyState != OPEN) {
- throw Error("readyState not OPEN");
+ if (this[_readyState] !== OPEN) {
+ throw new DOMException("readyState not OPEN", "InvalidStateError");
}
const sendTypedArray = (ta) => {
- this.#bufferedAmount += ta.size;
+ this[_bufferedAmount] += ta.byteLength;
core.opAsync("op_ws_send", {
- rid: this.#rid,
+ rid: this[_rid],
kind: "binary",
}, ta).then(() => {
- this.#bufferedAmount -= ta.size;
+ this[_bufferedAmount] -= ta.byteLength;
});
};
@@ -229,80 +303,94 @@
data.slice().arrayBuffer().then((ab) =>
sendTypedArray(new DataView(ab))
);
- } else if (
- data instanceof Int8Array || data instanceof Int16Array ||
- data instanceof Int32Array || data instanceof Uint8Array ||
- data instanceof Uint16Array || data instanceof Uint32Array ||
- data instanceof Uint8ClampedArray || data instanceof Float32Array ||
- data instanceof Float64Array || data instanceof DataView
- ) {
+ } else if (ArrayBuffer.isView(data)) {
sendTypedArray(data);
} else if (data instanceof ArrayBuffer) {
sendTypedArray(new DataView(data));
} else {
const string = String(data);
const d = core.encode(string);
- this.#bufferedAmount += d.size;
+ this[_bufferedAmount] += d.byteLength;
core.opAsync("op_ws_send", {
- rid: this.#rid,
+ rid: this[_rid],
kind: "text",
text: string,
}).then(() => {
- this.#bufferedAmount -= d.size;
+ this[_bufferedAmount] -= d.byteLength;
});
}
}
- close(code, reason) {
- if (code && !(code === 1000 || (3000 <= code && code < 5000))) {
+ close(code = undefined, reason = undefined) {
+ webidl.assertBranded(this, WebSocket);
+ const prefix = "Failed to execute 'close' on 'WebSocket'";
+
+ if (code !== undefined) {
+ code = webidl.converters["unsigned short"](code, {
+ prefix,
+ clamp: true,
+ context: "Argument 1",
+ });
+ }
+
+ if (reason !== undefined) {
+ reason = webidl.converters.USVString(reason, {
+ prefix,
+ context: "Argument 2",
+ });
+ }
+
+ if (
+ code !== undefined && !(code === 1000 || (3000 <= code && code < 5000))
+ ) {
throw new DOMException(
"The close code must be either 1000 or in the range of 3000 to 4999.",
- "NotSupportedError",
+ "InvalidAccessError",
);
}
- if (reason && core.encode(reason).byteLength > 123) {
+ if (reason !== undefined && core.encode(reason).byteLength > 123) {
throw new DOMException(
"The close reason may not be longer than 123 bytes.",
"SyntaxError",
);
}
- if (this.#readyState === CONNECTING) {
- this.#readyState = CLOSING;
- } else if (this.#readyState === OPEN) {
- this.#readyState = CLOSING;
+ if (this[_readyState] === CONNECTING) {
+ this[_readyState] = CLOSING;
+ } else if (this[_readyState] === OPEN) {
+ this[_readyState] = CLOSING;
core.opAsync("op_ws_close", {
- rid: this.#rid,
+ rid: this[_rid],
code,
reason,
}).then(() => {
- this.#readyState = CLOSED;
+ this[_readyState] = CLOSED;
const event = new CloseEvent("close", {
wasClean: true,
- code,
+ code: code ?? 1005,
reason,
});
event.target = this;
this.dispatchEvent(event);
- tryClose(this.#rid);
+ tryClose(this[_rid]);
});
}
}
async #eventLoop() {
- while (this.#readyState === OPEN) {
+ while (this[_readyState] === OPEN) {
const { kind, value } = await core.opAsync(
"op_ws_next_event",
- this.#rid,
+ this[_rid],
);
switch (kind) {
case "string": {
const event = new MessageEvent("message", {
data: value,
- origin: this.#url,
+ origin: this[_url],
});
event.target = this;
this.dispatchEvent(event);
@@ -319,7 +407,7 @@
const event = new MessageEvent("message", {
data,
- origin: this.#url,
+ origin: this[_url],
});
event.target = this;
this.dispatchEvent(event);
@@ -327,13 +415,13 @@
}
case "ping": {
core.opAsync("op_ws_send", {
- rid: this.#rid,
+ rid: this[_rid],
kind: "pong",
});
break;
}
case "close": {
- this.#readyState = CLOSED;
+ this[_readyState] = CLOSED;
const event = new CloseEvent("close", {
wasClean: true,
@@ -342,11 +430,11 @@
});
event.target = this;
this.dispatchEvent(event);
- tryClose(this.#rid);
+ tryClose(this[_rid]);
break;
}
case "error": {
- this.#readyState = CLOSED;
+ this[_readyState] = CLOSED;
const errorEv = new ErrorEvent("error", {
message: value,
@@ -357,7 +445,7 @@
const closeEv = new CloseEvent("close");
closeEv.target = this;
this.dispatchEvent(closeEv);
- tryClose(this.#rid);
+ tryClose(this[_rid]);
break;
}
}
@@ -385,5 +473,7 @@
defineEventHandler(WebSocket.prototype, "close");
defineEventHandler(WebSocket.prototype, "open");
+ webidl.configurePrototype(WebSocket);
+
window.__bootstrap.webSocket = { WebSocket };
})(this);
diff --git a/tools/wpt/config.json b/tools/wpt/config.json
index f146607c1..3bcd6612c 100644
--- a/tools/wpt/config.json
+++ b/tools/wpt/config.json
@@ -1,6 +1,11 @@
{
"check_subdomains": false,
"ssl": {
- "type": "pregenerated"
+ "type": "pregenerated",
+ "pregenerated": {
+ "ca_cert_path": "../../tools/wpt/certs/cacert.pem",
+ "host_cert_path": "../../tools/wpt/certs/web-platform.test.pem",
+ "host_key_path": "../../tools/wpt/certs/web-platform.test.key"
+ }
}
}
diff --git a/tools/wpt/expectation.json b/tools/wpt/expectation.json
index 0001f92d3..962c12de6 100644
--- a/tools/wpt/expectation.json
+++ b/tools/wpt/expectation.json
@@ -1023,5 +1023,190 @@
"set-blob.any.html": true,
"set.any.html": true
}
+ },
+ "websockets": {
+ "Close-1000-reason.any.html": true,
+ "Close-1000-reason.any.html?wpt_flags=h2": false,
+ "Close-1000-reason.any.html?wss": true,
+ "Close-1000-verify-code.any.html": true,
+ "Close-1000-verify-code.any.html?wpt_flags=h2": false,
+ "Close-1000-verify-code.any.html?wss": true,
+ "Close-1000.any.html": true,
+ "Close-1000.any.html?wpt_flags=h2": false,
+ "Close-1000.any.html?wss": true,
+ "Close-1005-verify-code.any.html": true,
+ "Close-1005-verify-code.any.html?wpt_flags=h2": false,
+ "Close-1005-verify-code.any.html?wss": true,
+ "Close-1005.any.html": true,
+ "Close-1005.any.html?wpt_flags=h2": false,
+ "Close-1005.any.html?wss": true,
+ "Close-2999-reason.any.html": true,
+ "Close-2999-reason.any.html?wpt_flags=h2": false,
+ "Close-2999-reason.any.html?wss": true,
+ "Close-3000-reason.any.html": true,
+ "Close-3000-reason.any.html?wpt_flags=h2": false,
+ "Close-3000-reason.any.html?wss": true,
+ "Close-3000-verify-code.any.html": true,
+ "Close-3000-verify-code.any.html?wpt_flags=h2": false,
+ "Close-3000-verify-code.any.html?wss": true,
+ "Close-4999-reason.any.html": true,
+ "Close-4999-reason.any.html?wpt_flags=h2": false,
+ "Close-4999-reason.any.html?wss": true,
+ "Close-Reason-124Bytes.any.html": true,
+ "Close-Reason-124Bytes.any.html?wpt_flags=h2": false,
+ "Close-Reason-124Bytes.any.html?wss": true,
+ "Close-onlyReason.any.html": true,
+ "Close-onlyReason.any.html?wpt_flags=h2": false,
+ "Close-onlyReason.any.html?wss": true,
+ "Close-readyState-Closed.any.html": true,
+ "Close-readyState-Closed.any.html?wpt_flags=h2": false,
+ "Close-readyState-Closed.any.html?wss": true,
+ "Close-readyState-Closing.any.html": true,
+ "Close-readyState-Closing.any.html?wpt_flags=h2": false,
+ "Close-readyState-Closing.any.html?wss": true,
+ "Close-reason-unpaired-surrogates.any.html": true,
+ "Close-reason-unpaired-surrogates.any.html?wpt_flags=h2": false,
+ "Close-reason-unpaired-surrogates.any.html?wss": true,
+ "Close-server-initiated-close.any.html": true,
+ "Close-server-initiated-close.any.html?wpt_flags=h2": false,
+ "Close-server-initiated-close.any.html?wss": true,
+ "Close-undefined.any.html": true,
+ "Close-undefined.any.html?wpt_flags=h2": false,
+ "Close-undefined.any.html?wss": true,
+ "Create-asciiSep-protocol-string.any.html": true,
+ "Create-asciiSep-protocol-string.any.html?wpt_flags=h2": true,
+ "Create-asciiSep-protocol-string.any.html?wss": true,
+ "Create-blocked-port.any.html": true,
+ "Create-blocked-port.any.html?wpt_flags=h2": [
+ "Basic check"
+ ],
+ "Create-blocked-port.any.html?wss": true,
+ "Create-extensions-empty.any.html": true,
+ "Create-extensions-empty.any.html?wpt_flags=h2": false,
+ "Create-extensions-empty.any.html?wss": true,
+ "Create-invalid-urls.any.html": true,
+ "Create-invalid-urls.any.html?wpt_flags=h2": true,
+ "Create-invalid-urls.any.html?wss": true,
+ "Create-non-absolute-url.any.html": true,
+ "Create-non-absolute-url.any.html?wpt_flags=h2": true,
+ "Create-non-absolute-url.any.html?wss": true,
+ "Create-nonAscii-protocol-string.any.html": true,
+ "Create-nonAscii-protocol-string.any.html?wpt_flags=h2": true,
+ "Create-nonAscii-protocol-string.any.html?wss": true,
+ "Create-on-worker-shutdown.any.html": false,
+ "Create-protocol-with-space.any.html": true,
+ "Create-protocol-with-space.any.html?wpt_flags=h2": true,
+ "Create-protocol-with-space.any.html?wss": true,
+ "Create-protocols-repeated-case-insensitive.any.html": true,
+ "Create-protocols-repeated-case-insensitive.any.html?wpt_flags=h2": true,
+ "Create-protocols-repeated-case-insensitive.any.html?wss": true,
+ "Create-protocols-repeated.any.html": true,
+ "Create-protocols-repeated.any.html?wpt_flags=h2": true,
+ "Create-protocols-repeated.any.html?wss": true,
+ "Create-url-with-space.any.html": true,
+ "Create-url-with-space.any.html?wpt_flags=h2": true,
+ "Create-url-with-space.any.html?wss": true,
+ "Create-valid-url-array-protocols.any.html": true,
+ "Create-valid-url-array-protocols.any.html?wpt_flags=h2": false,
+ "Create-valid-url-array-protocols.any.html?wss": true,
+ "Create-valid-url-binaryType-blob.any.html": true,
+ "Create-valid-url-binaryType-blob.any.html?wpt_flags=h2": false,
+ "Create-valid-url-binaryType-blob.any.html?wss": true,
+ "Create-valid-url-protocol-empty.any.html": true,
+ "Create-valid-url-protocol-empty.any.html?wpt_flags=h2": true,
+ "Create-valid-url-protocol-empty.any.html?wss": true,
+ "Create-valid-url-protocol-setCorrectly.any.html": true,
+ "Create-valid-url-protocol-setCorrectly.any.html?wpt_flags=h2": false,
+ "Create-valid-url-protocol-setCorrectly.any.html?wss": true,
+ "Create-valid-url-protocol-string.any.html": true,
+ "Create-valid-url-protocol-string.any.html?wpt_flags=h2": false,
+ "Create-valid-url-protocol-string.any.html?wss": true,
+ "Create-valid-url-protocol.any.html": true,
+ "Create-valid-url-protocol.any.html?wpt_flags=h2": false,
+ "Create-valid-url-protocol.any.html?wss": true,
+ "Create-valid-url.any.html": true,
+ "Create-valid-url.any.html?wpt_flags=h2": false,
+ "Create-valid-url.any.html?wss": true,
+ "Create-wrong-scheme.any.html": true,
+ "Create-wrong-scheme.any.html?wpt_flags=h2": true,
+ "Create-wrong-scheme.any.html?wss": true,
+ "Send-0byte-data.any.html": true,
+ "Send-0byte-data.any.html?wpt_flags=h2": false,
+ "Send-0byte-data.any.html?wss": true,
+ "Send-65K-data.any.html": true,
+ "Send-65K-data.any.html?wpt_flags=h2": false,
+ "Send-65K-data.any.html?wss": true,
+ "Send-before-open.any.html": true,
+ "Send-before-open.any.html?wpt_flags=h2": true,
+ "Send-before-open.any.html?wss": true,
+ "Send-binary-65K-arraybuffer.any.html": true,
+ "Send-binary-65K-arraybuffer.any.html?wpt_flags=h2": false,
+ "Send-binary-65K-arraybuffer.any.html?wss": true,
+ "Send-binary-arraybuffer.any.html": true,
+ "Send-binary-arraybuffer.any.html?wpt_flags=h2": false,
+ "Send-binary-arraybuffer.any.html?wss": true,
+ "Send-binary-arraybufferview-float32.any.html": true,
+ "Send-binary-arraybufferview-float32.any.html?wpt_flags=h2": false,
+ "Send-binary-arraybufferview-float32.any.html?wss": true,
+ "Send-binary-arraybufferview-float64.any.html": true,
+ "Send-binary-arraybufferview-float64.any.html?wpt_flags=h2": false,
+ "Send-binary-arraybufferview-float64.any.html?wss": true,
+ "Send-binary-arraybufferview-int16-offset.any.html": true,
+ "Send-binary-arraybufferview-int16-offset.any.html?wpt_flags=h2": false,
+ "Send-binary-arraybufferview-int16-offset.any.html?wss": true,
+ "Send-binary-arraybufferview-int32.any.html": true,
+ "Send-binary-arraybufferview-int32.any.html?wpt_flags=h2": false,
+ "Send-binary-arraybufferview-int32.any.html?wss": true,
+ "Send-binary-arraybufferview-int8.any.html": true,
+ "Send-binary-arraybufferview-int8.any.html?wpt_flags=h2": false,
+ "Send-binary-arraybufferview-int8.any.html?wss": true,
+ "Send-binary-arraybufferview-uint16-offset-length.any.html": true,
+ "Send-binary-arraybufferview-uint16-offset-length.any.html?wpt_flags=h2": false,
+ "Send-binary-arraybufferview-uint16-offset-length.any.html?wss": true,
+ "Send-binary-arraybufferview-uint32-offset.any.html": true,
+ "Send-binary-arraybufferview-uint32-offset.any.html?wpt_flags=h2": false,
+ "Send-binary-arraybufferview-uint32-offset.any.html?wss": true,
+ "Send-binary-arraybufferview-uint8-offset-length.any.html": true,
+ "Send-binary-arraybufferview-uint8-offset-length.any.html?wpt_flags=h2": false,
+ "Send-binary-arraybufferview-uint8-offset-length.any.html?wss": true,
+ "Send-binary-arraybufferview-uint8-offset.any.html": true,
+ "Send-binary-arraybufferview-uint8-offset.any.html?wpt_flags=h2": false,
+ "Send-binary-arraybufferview-uint8-offset.any.html?wss": true,
+ "Send-binary-blob.any.html": true,
+ "Send-binary-blob.any.html?wpt_flags=h2": false,
+ "Send-binary-blob.any.html?wss": true,
+ "Send-data.any.html": true,
+ "Send-data.any.html?wpt_flags=h2": false,
+ "Send-data.any.html?wss": true,
+ "Send-null.any.html": true,
+ "Send-null.any.html?wpt_flags=h2": false,
+ "Send-null.any.html?wss": true,
+ "Send-paired-surrogates.any.html": true,
+ "Send-paired-surrogates.any.html?wpt_flags=h2": false,
+ "Send-paired-surrogates.any.html?wss": true,
+ "Send-unicode-data.any.html": true,
+ "Send-unicode-data.any.html?wpt_flags=h2": false,
+ "Send-unicode-data.any.html?wss": true,
+ "Send-unpaired-surrogates.any.html": true,
+ "Send-unpaired-surrogates.any.html?wpt_flags=h2": false,
+ "Send-unpaired-surrogates.any.html?wss": true,
+ "basic-auth.any.html?wpt_flags=h2": false,
+ "basic-auth.any.html?wss": false,
+ "binaryType-wrong-value.any.html": true,
+ "binaryType-wrong-value.any.html?wpt_flags=h2": false,
+ "binaryType-wrong-value.any.html?wss": true,
+ "bufferedAmount-unchanged-by-sync-xhr.any.html": false,
+ "bufferedAmount-unchanged-by-sync-xhr.any.html?wpt_flags=h2": false,
+ "bufferedAmount-unchanged-by-sync-xhr.any.html?wss": false,
+ "close-invalid.any.html": true,
+ "close-invalid.any.html?wpt_flags=h2": true,
+ "close-invalid.any.html?wss": true,
+ "constructor.any.html": true,
+ "constructor.any.html?wpt_flags=h2": true,
+ "constructor.any.html?wss": true,
+ "eventhandlers.any.html": false,
+ "eventhandlers.any.html?wpt_flags=h2": false,
+ "eventhandlers.any.html?wss": false,
+ "referrer.any.html": true
}
}