diff --git a/ext/fetch/20_headers.js b/ext/fetch/20_headers.js index 67c5d0e652..c35c745b58 100644 --- a/ext/fetch/20_headers.js +++ b/ext/fetch/20_headers.js @@ -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 diff --git a/ext/web/00_infra.js b/ext/web/00_infra.js index 7c065bcd3a..7098c95773 100644 --- a/ext/web/00_infra.js +++ b/ext/web/00_infra.js @@ -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, diff --git a/ext/web/internal.d.ts b/ext/web/internal.d.ts index 94fc9c1968..89fdbacf3c 100644 --- a/ext/web/internal.d.ts +++ b/ext/web/internal.d.ts @@ -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;