-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
chore: align Headers
to spec
#10199
chore: align Headers
to spec
#10199
Conversation
22325da
to
9bd1500
Compare
const ASCII_DIGIT = ["\u0030-\u0039"]; | ||
const ASCII_UPPER_ALPHA = ["\u0041-\u005A"]; | ||
const ASCII_LOWER_ALPHA = ["\u0061-\u007A"]; | ||
const ASCII_ALPHA = [...ASCII_UPPER_ALPHA, ...ASCII_LOWER_ALPHA]; | ||
const ASCII_ALPHANUMERIC = [...ASCII_DIGIT, ...ASCII_ALPHA]; | ||
|
||
const HTTP_TAB_OR_SPACE = ["\u0009", "\u0020"]; | ||
const HTTP_WHITESPACE = ["\u000A", "\u000D", ...HTTP_TAB_OR_SPACE]; | ||
|
||
const HTTP_TOKEN_CODE_POINT = [ | ||
"\u0021", | ||
"\u0023", | ||
"\u0024", | ||
"\u0025", | ||
"\u0026", | ||
"\u0027", | ||
"\u002A", | ||
"\u002B", | ||
"\u002D", | ||
"\u002E", | ||
"\u005E", | ||
"\u005F", | ||
"\u0060", | ||
"\u007C", | ||
"\u007E", | ||
...ASCII_ALPHANUMERIC, | ||
]; | ||
const HTTP_TOKEN_CODE_POINT_RE = new RegExp( | ||
`^[${regexMatcher(HTTP_TOKEN_CODE_POINT)}]+$`, | ||
); | ||
const HTTP_QUOTED_STRING_TOKEN_POINT = [ | ||
"\u0009", | ||
"\u0020-\u007E", | ||
"\u0080-\u00FF", | ||
]; | ||
const HTTP_QUOTED_STRING_TOKEN_POINT_RE = new RegExp( | ||
`^[${regexMatcher(HTTP_QUOTED_STRING_TOKEN_POINT)}]+$`, | ||
); | ||
const HTTP_WHITESPACE_MATCHER = regexMatcher(HTTP_WHITESPACE); | ||
const HTTP_WHITESPACE_PREFIX_RE = new RegExp( | ||
`^[${HTTP_WHITESPACE_MATCHER}]+`, | ||
"g", | ||
); | ||
const HTTP_WHITESPACE_SUFFIX_RE = new RegExp( | ||
`[${HTTP_WHITESPACE_MATCHER}]+$`, | ||
"g", | ||
); | ||
|
||
/** | ||
* Turn a string of chars into a regex safe matcher. | ||
* @param {string[]} chars | ||
* @returns {string} | ||
*/ | ||
function regexMatcher(chars) { | ||
const matchers = chars.map((char) => { | ||
if (char.length === 1) { | ||
return `\\u${char.charCodeAt(0).toString(16).padStart(4, "0")}`; | ||
} else if (char.length === 3 && char[1] === "-") { | ||
return `\\u${char.charCodeAt(0).toString(16).padStart(4, "0")}-\\u${ | ||
char.charCodeAt(2).toString(16).padStart(4, "0") | ||
}`; | ||
} else { | ||
throw TypeError("unreachable"); | ||
} | ||
}); | ||
return matchers.join(""); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is all just moved from //op_crates/web/01_mimesniff.js
"headers-basic.any.js": true, | ||
"headers-casing.any.js": true, | ||
"headers-combine.any.js": true, | ||
"headers-errors.any.js": true, | ||
"headers-normalize.any.js": true, | ||
"headers-record.any.js": true, | ||
"headers-structure.any.js": true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All relevant tests pass.
The |
unitTest(function headersSetDuplicateCookieKey(): void { | ||
const headers = new Headers([["Set-Cookie", "foo=bar"]]); | ||
headers.set("set-Cookie", "foo=baz"); | ||
headers.set("set-cookie", "bar=qat"); | ||
const actual = [...headers]; | ||
assertEquals(actual, [ | ||
["set-cookie", "foo=baz"], | ||
["set-cookie", "bar=qat"], | ||
]); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test is plain wrong. headers.set
is not the same as append. It removes existing headers of that name before insertion. See https://fetch.spec.whatwg.org/#concept-header-list-set
83af2b3
to
f337975
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
f337975
to
a10296d
Compare
This commit aligns `Headers` to spec. It also removes the now unused 03_dom_iterable.js file. We now pass all relevant `Headers` WPT. We do not implement any sort of header filtering, as we are a server side runtime. This is likely not the most efficient implementation of `Headers` yet. It is however spec compliant. Once all the APIs in the `HTTP` hot loop are correct we can start optimizing them. It is likely that this commit reduces bench throughput temporarily.
a10296d
to
b3cb67e
Compare
This is most likely caused by the O(n^2) complexity of https://github.com/denoland/deno/blob/main/extensions/fetch/20_headers.js#L178-L207 |
This commit aligns
Headers
to spec. It also removes the now unused03_dom_iterable.js file. We now pass all relevant
Headers
WPT. We donot implement any sort of header filtering, as we are a server side
runtime.
This is likely not the most efficient implementation of
Headers
yet. It ishowever spec compliant. Once all the APIs in the
HTTP
hot loop arecorrect we can start optimizing them. It is likely that this reduces bench
throughput temporarily.