diff --git a/lib/core/request.js b/lib/core/request.js index b0bd870e33a..0f89f318568 100644 --- a/lib/core/request.js +++ b/lib/core/request.js @@ -80,7 +80,7 @@ class Request { if (typeof method !== 'string') { throw new InvalidArgumentError('method must be a string') - } else if (tokenRegExp.exec(method) === null) { + } else if (!util.isValidHTTPToken(method)) { throw new InvalidArgumentError('invalid request method') } diff --git a/lib/core/util.js b/lib/core/util.js index 75d31888221..49d1c9938ed 100644 --- a/lib/core/util.js +++ b/lib/core/util.js @@ -442,6 +442,52 @@ function toUSVString (val) { return `${val}` } +/** + * @see https://tools.ietf.org/html/rfc7230#section-3.2.6 + * @param {number} c + */ +function isTokenCharCode (c) { + switch (c) { + case 0x22: + case 0x28: + case 0x29: + case 0x2c: + case 0x2f: + case 0x3a: + case 0x3b: + case 0x3c: + case 0x3d: + case 0x3e: + case 0x3f: + case 0x40: + case 0x5b: + case 0x5c: + case 0x5d: + case 0x7b: + case 0x7d: + // DQUOTE and "(),/:;<=>?@[\]{}" + return false + default: + // VCHAR %x21-7E + return c >= 0x21 && c <= 0x7e + } +} + +/** + * @param {string} characters + */ +function isValidHTTPToken (characters) { + if (characters.length === 0) { + return false + } + for (let i = 0; i < characters.length; ++i) { + if (!isTokenCharCode(characters.charCodeAt(i))) { + return false + } + } + return true +} + // Parsed accordingly to RFC 9110 // https://www.rfc-editor.org/rfc/rfc9110#field.content-range function parseRangeHeader (range) { @@ -490,6 +536,8 @@ module.exports = { isFormDataLike, buildURL, addAbortListener, + isValidHTTPToken, + isTokenCharCode, parseRangeHeader, nodeMajor, nodeMinor, diff --git a/lib/fetch/util.js b/lib/fetch/util.js index b729d70d1e8..9843f97444b 100644 --- a/lib/fetch/util.js +++ b/lib/fetch/util.js @@ -3,7 +3,7 @@ const { redirectStatusSet, referrerPolicySet: referrerPolicyTokens, badPortsSet } = require('./constants') const { getGlobalOrigin } = require('./global') const { performance } = require('perf_hooks') -const { isBlobLike, toUSVString, ReadableStreamFrom } = require('../core/util') +const { isBlobLike, toUSVString, ReadableStreamFrom, isValidHTTPToken } = require('../core/util') const assert = require('assert') const { isUint8Array } = require('util/types') @@ -103,52 +103,6 @@ function isValidReasonPhrase (statusText) { return true } -/** - * @see https://tools.ietf.org/html/rfc7230#section-3.2.6 - * @param {number} c - */ -function isTokenCharCode (c) { - switch (c) { - case 0x22: - case 0x28: - case 0x29: - case 0x2c: - case 0x2f: - case 0x3a: - case 0x3b: - case 0x3c: - case 0x3d: - case 0x3e: - case 0x3f: - case 0x40: - case 0x5b: - case 0x5c: - case 0x5d: - case 0x7b: - case 0x7d: - // DQUOTE and "(),/:;<=>?@[\]{}" - return false - default: - // VCHAR %x21-7E - return c >= 0x21 && c <= 0x7e - } -} - -/** - * @param {string} characters - */ -function isValidHTTPToken (characters) { - if (characters.length === 0) { - return false - } - for (let i = 0; i < characters.length; ++i) { - if (!isTokenCharCode(characters.charCodeAt(i))) { - return false - } - } - return true -} - /** * @see https://fetch.spec.whatwg.org/#header-name * @param {string} potentialValue