mirror of
https://github.com/denoland/deno.git
synced 2024-11-28 16:20:57 -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
df94139aa8
commit
b1eeaf71ff
3 changed files with 36 additions and 14 deletions
|
@ -15,12 +15,11 @@
|
|||
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,
|
||||
httpTrim,
|
||||
} = window.__bootstrap.infra;
|
||||
const {
|
||||
ArrayIsArray,
|
||||
|
@ -59,17 +58,7 @@
|
|||
* @returns {string}
|
||||
*/
|
||||
function normalizeHeaderValue(potentialValue) {
|
||||
potentialValue = StringPrototypeReplaceAll(
|
||||
potentialValue,
|
||||
HTTP_WHITESPACE_PREFIX_RE,
|
||||
"",
|
||||
);
|
||||
potentialValue = StringPrototypeReplaceAll(
|
||||
potentialValue,
|
||||
HTTP_WHITESPACE_SUFFIX_RE,
|
||||
"",
|
||||
);
|
||||
return potentialValue;
|
||||
return httpTrim(potentialValue);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -95,7 +84,7 @@
|
|||
|
||||
// Regex matching illegal chars in a header value
|
||||
// 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
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
TypeError,
|
||||
ArrayPrototypeJoin,
|
||||
StringPrototypeCharAt,
|
||||
StringPrototypeMatch,
|
||||
StringPrototypeSlice,
|
||||
String,
|
||||
StringPrototypeReplace,
|
||||
|
@ -75,6 +76,9 @@
|
|||
"g",
|
||||
);
|
||||
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(
|
||||
`^[${HTTP_WHITESPACE_MATCHER}]+`,
|
||||
"g",
|
||||
|
@ -237,6 +241,33 @@
|
|||
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 = {
|
||||
collectSequenceOfCodepoints,
|
||||
ASCII_DIGIT,
|
||||
|
@ -254,6 +285,7 @@
|
|||
HTTP_TAB_OR_SPACE_SUFFIX_RE,
|
||||
HTTP_WHITESPACE_PREFIX_RE,
|
||||
HTTP_WHITESPACE_SUFFIX_RE,
|
||||
httpTrim,
|
||||
regexMatcher,
|
||||
byteUpperCase,
|
||||
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_WHITESPACE_PREFIX_RE: RegExp;
|
||||
HTTP_WHITESPACE_SUFFIX_RE: RegExp;
|
||||
httpTrim(s: string): string;
|
||||
regexMatcher(chars: string[]): string;
|
||||
byteUpperCase(s: string): string;
|
||||
byteLowerCase(s: string): string;
|
||||
|
|
Loading…
Reference in a new issue