mirror of
https://github.com/denoland/deno.git
synced 2024-12-24 08:09:08 -05:00
perf(web): ~400x faster http header trimming (#12277)
Use a regex substring match with a first/last char fastpath instead of 2 regex replaces. Roughly ~400x faster (423ms vs 0.7ms in profiled runs)
This commit is contained in:
parent
ee2e25fba7
commit
68e5cdaff0
3 changed files with 36 additions and 14 deletions
|
@ -15,12 +15,11 @@
|
||||||
const {
|
const {
|
||||||
HTTP_TAB_OR_SPACE_PREFIX_RE,
|
HTTP_TAB_OR_SPACE_PREFIX_RE,
|
||||||
HTTP_TAB_OR_SPACE_SUFFIX_RE,
|
HTTP_TAB_OR_SPACE_SUFFIX_RE,
|
||||||
HTTP_WHITESPACE_PREFIX_RE,
|
|
||||||
HTTP_WHITESPACE_SUFFIX_RE,
|
|
||||||
HTTP_TOKEN_CODE_POINT_RE,
|
HTTP_TOKEN_CODE_POINT_RE,
|
||||||
byteLowerCase,
|
byteLowerCase,
|
||||||
collectSequenceOfCodepoints,
|
collectSequenceOfCodepoints,
|
||||||
collectHttpQuotedString,
|
collectHttpQuotedString,
|
||||||
|
httpTrim,
|
||||||
} = window.__bootstrap.infra;
|
} = window.__bootstrap.infra;
|
||||||
const {
|
const {
|
||||||
ArrayIsArray,
|
ArrayIsArray,
|
||||||
|
@ -59,17 +58,7 @@
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
function normalizeHeaderValue(potentialValue) {
|
function normalizeHeaderValue(potentialValue) {
|
||||||
potentialValue = StringPrototypeReplaceAll(
|
return httpTrim(potentialValue);
|
||||||
potentialValue,
|
|
||||||
HTTP_WHITESPACE_PREFIX_RE,
|
|
||||||
"",
|
|
||||||
);
|
|
||||||
potentialValue = StringPrototypeReplaceAll(
|
|
||||||
potentialValue,
|
|
||||||
HTTP_WHITESPACE_SUFFIX_RE,
|
|
||||||
"",
|
|
||||||
);
|
|
||||||
return potentialValue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -95,7 +84,7 @@
|
||||||
|
|
||||||
// Regex matching illegal chars in a header value
|
// Regex matching illegal chars in a header value
|
||||||
// deno-lint-ignore no-control-regex
|
// deno-lint-ignore no-control-regex
|
||||||
const ILLEGAL_VALUE_CHARS = /[\x00\x0A\x0D]/;
|
const ILLEGAL_VALUE_CHARS = /[\x00\x0A\x0D]/g;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* https://fetch.spec.whatwg.org/#concept-headers-append
|
* https://fetch.spec.whatwg.org/#concept-headers-append
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
TypeError,
|
TypeError,
|
||||||
ArrayPrototypeJoin,
|
ArrayPrototypeJoin,
|
||||||
StringPrototypeCharAt,
|
StringPrototypeCharAt,
|
||||||
|
StringPrototypeMatch,
|
||||||
StringPrototypeSlice,
|
StringPrototypeSlice,
|
||||||
String,
|
String,
|
||||||
StringPrototypeReplace,
|
StringPrototypeReplace,
|
||||||
|
@ -75,6 +76,9 @@
|
||||||
"g",
|
"g",
|
||||||
);
|
);
|
||||||
const HTTP_WHITESPACE_MATCHER = regexMatcher(HTTP_WHITESPACE);
|
const HTTP_WHITESPACE_MATCHER = regexMatcher(HTTP_WHITESPACE);
|
||||||
|
const HTTP_BETWEEN_WHITESPACE = new RegExp(
|
||||||
|
`^[${HTTP_WHITESPACE_MATCHER}]*(.*?)[${HTTP_WHITESPACE_MATCHER}]*$`,
|
||||||
|
);
|
||||||
const HTTP_WHITESPACE_PREFIX_RE = new RegExp(
|
const HTTP_WHITESPACE_PREFIX_RE = new RegExp(
|
||||||
`^[${HTTP_WHITESPACE_MATCHER}]+`,
|
`^[${HTTP_WHITESPACE_MATCHER}]+`,
|
||||||
"g",
|
"g",
|
||||||
|
@ -237,6 +241,33 @@
|
||||||
return core.opSync("op_base64_decode", data);
|
return core.opSync("op_base64_decode", data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} char
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
function isHttpWhitespace(char) {
|
||||||
|
switch (char) {
|
||||||
|
case "\u0009":
|
||||||
|
case "\u000A":
|
||||||
|
case "\u000D":
|
||||||
|
case "\u0020":
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} s
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
function httpTrim(s) {
|
||||||
|
if (!isHttpWhitespace(s[0]) && !isHttpWhitespace(s[s.length - 1])) {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
return StringPrototypeMatch(s, HTTP_BETWEEN_WHITESPACE)?.[1] ?? "";
|
||||||
|
}
|
||||||
|
|
||||||
window.__bootstrap.infra = {
|
window.__bootstrap.infra = {
|
||||||
collectSequenceOfCodepoints,
|
collectSequenceOfCodepoints,
|
||||||
ASCII_DIGIT,
|
ASCII_DIGIT,
|
||||||
|
@ -254,6 +285,7 @@
|
||||||
HTTP_TAB_OR_SPACE_SUFFIX_RE,
|
HTTP_TAB_OR_SPACE_SUFFIX_RE,
|
||||||
HTTP_WHITESPACE_PREFIX_RE,
|
HTTP_WHITESPACE_PREFIX_RE,
|
||||||
HTTP_WHITESPACE_SUFFIX_RE,
|
HTTP_WHITESPACE_SUFFIX_RE,
|
||||||
|
httpTrim,
|
||||||
regexMatcher,
|
regexMatcher,
|
||||||
byteUpperCase,
|
byteUpperCase,
|
||||||
byteLowerCase,
|
byteLowerCase,
|
||||||
|
|
1
ext/web/internal.d.ts
vendored
1
ext/web/internal.d.ts
vendored
|
@ -29,6 +29,7 @@ declare namespace globalThis {
|
||||||
HTTP_TAB_OR_SPACE_SUFFIX_RE: RegExp;
|
HTTP_TAB_OR_SPACE_SUFFIX_RE: RegExp;
|
||||||
HTTP_WHITESPACE_PREFIX_RE: RegExp;
|
HTTP_WHITESPACE_PREFIX_RE: RegExp;
|
||||||
HTTP_WHITESPACE_SUFFIX_RE: RegExp;
|
HTTP_WHITESPACE_SUFFIX_RE: RegExp;
|
||||||
|
httpTrim(s: string): string;
|
||||||
regexMatcher(chars: string[]): string;
|
regexMatcher(chars: string[]): string;
|
||||||
byteUpperCase(s: string): string;
|
byteUpperCase(s: string): string;
|
||||||
byteLowerCase(s: string): string;
|
byteLowerCase(s: string): string;
|
||||||
|
|
Loading…
Reference in a new issue