summaryrefslogtreecommitdiff
path: root/op_crates/fetch/20_headers.js
diff options
context:
space:
mode:
authorLuca Casonato <lucacasonato@yahoo.com>2021-04-20 14:47:22 +0200
committerGitHub <noreply@github.com>2021-04-20 14:47:22 +0200
commit9e6cd91014ac4a0d34556b0d09cbe25e4e0930c6 (patch)
tree4523790510a17676c987039feb03f208a258dc16 /op_crates/fetch/20_headers.js
parent115197ffb06aad2a3045e8478980ab911b5a5eeb (diff)
chore: align fetch to spec (#10203)
This commit aligns the `fetch` API and the `Request` / `Response` classes belonging to it to the spec. This commit enables all the relevant `fetch` WPT tests. Spec compliance is now at around 90%. Performance is essentially identical now (within 1% of 1.9.0).
Diffstat (limited to 'op_crates/fetch/20_headers.js')
-rw-r--r--op_crates/fetch/20_headers.js88
1 files changed, 86 insertions, 2 deletions
diff --git a/op_crates/fetch/20_headers.js b/op_crates/fetch/20_headers.js
index ce46e5dee..3c6fc0b26 100644
--- a/op_crates/fetch/20_headers.js
+++ b/op_crates/fetch/20_headers.js
@@ -14,10 +14,14 @@
((window) => {
const webidl = window.__bootstrap.webidl;
const {
+ HTTP_TAB_OR_SPACE_PREFIX_RE,
+ HTTP_TAB_OR_SPACE_SUFFIX_RE,
HTTP_WHITESPACE_PREFIX_RE,
HTTP_WHITESPACE_SUFFIX_RE,
HTTP_TOKEN_CODE_POINT_RE,
byteLowerCase,
+ collectSequenceOfCodepoints,
+ collectHttpQuotedString,
} = window.__bootstrap.infra;
const _headerList = Symbol("header list");
@@ -35,7 +39,7 @@
*/
/**
- * @typedef {string} potentialValue
+ * @param {string} potentialValue
* @returns {string}
*/
function normalizeHeaderValue(potentialValue) {
@@ -103,6 +107,7 @@
}
/**
+ * https://fetch.spec.whatwg.org/#concept-header-list-get
* @param {HeaderList} list
* @param {string} name
*/
@@ -118,10 +123,56 @@
}
}
+ /**
+ * https://fetch.spec.whatwg.org/#concept-header-list-get-decode-split
+ * @param {HeaderList} list
+ * @param {string} name
+ * @returns {string[] | null}
+ */
+ function getDecodeSplitHeader(list, name) {
+ const initialValue = getHeader(list, name);
+ if (initialValue === null) return null;
+ const input = initialValue;
+ let position = 0;
+ const values = [];
+ let value = "";
+ while (position < initialValue.length) {
+ // 7.1. collect up to " or ,
+ const res = collectSequenceOfCodepoints(
+ initialValue,
+ position,
+ (c) => c !== "\u0022" && c !== "\u002C",
+ );
+ value += res.result;
+ position = res.position;
+
+ if (position < initialValue.length) {
+ if (input[position] === "\u0022") {
+ const res = collectHttpQuotedString(input, position, false);
+ value += res.result;
+ position = res.position;
+ if (position < initialValue.length) {
+ continue;
+ }
+ } else {
+ if (input[position] !== "\u002C") throw new TypeError("Unreachable");
+ position += 1;
+ }
+ }
+
+ value = value.replaceAll(HTTP_TAB_OR_SPACE_PREFIX_RE, "");
+ value = value.replaceAll(HTTP_TAB_OR_SPACE_SUFFIX_RE, "");
+
+ values.push(value);
+ value = "";
+ }
+ return values;
+ }
+
class Headers {
/** @type {HeaderList} */
[_headerList] = [];
- /** @type {"immutable"| "request"| "request-no-cors"| "response" | "none"} */
+ /** @type {"immutable" | "request" | "request-no-cors" | "response" | "none"} */
[_guard];
get [_iterableHeaders]() {
@@ -359,7 +410,40 @@
Headers,
);
+ /**
+ * @param {HeaderList} list
+ * @param {"immutable" | "request" | "request-no-cors" | "response" | "none"} guard
+ * @returns {Headers}
+ */
+ function headersFromHeaderList(list, guard) {
+ const headers = webidl.createBranded(Headers);
+ headers[_headerList] = list;
+ headers[_guard] = guard;
+ return headers;
+ }
+
+ /**
+ * @param {Headers}
+ * @returns {HeaderList}
+ */
+ function headerListFromHeaders(headers) {
+ return headers[_headerList];
+ }
+
+ /**
+ * @param {Headers}
+ * @returns {"immutable" | "request" | "request-no-cors" | "response" | "none"}
+ */
+ function guardFromHeaders(headers) {
+ return headers[_guard];
+ }
+
window.__bootstrap.headers = {
Headers,
+ headersFromHeaderList,
+ headerListFromHeaders,
+ fillHeaders,
+ getDecodeSplitHeader,
+ guardFromHeaders,
};
})(this);