http: optimize checkIsHttpToken for short strings
Some checks are pending
Coverage Linux (without intl) / coverage-linux-without-intl (push) Waiting to run
Coverage Linux / coverage-linux (push) Waiting to run
Coverage Windows / coverage-windows (push) Waiting to run
Test and upload documentation to artifacts / build-docs (push) Waiting to run
Notify on Push / Notify on Force Push on `main` (push) Waiting to run
Notify on Push / Notify on Push on `main` that lacks metadata (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Waiting to run

Use lookup table instead of regex for strings shorter than 10
characters to improve performance for common short header names
while maintaining compatibility.

PR-URL: https://github.com/nodejs/node/pull/59832
Reviewed-By: Ethan Arrowood <ethan@arrowood.dev>
Reviewed-By: Tim Perry <pimterry@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
This commit is contained in:
방진혁 2025-09-14 09:40:06 +09:00 committed by GitHub
parent c85460b0ad
commit c8c6bfab23
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -24,6 +24,7 @@
const {
MathMin,
Symbol,
Uint8Array,
} = primordials;
const { setImmediate } = require('timers');
@ -205,7 +206,30 @@ function freeParser(parser, req, socket) {
}
}
// Character code ranges for valid HTTP tokens
// Valid chars: ^_`a-zA-Z-0-9!#$%&'*+.|~
// Based on RFC 7230 Section 3.2.6 token definition
// See https://tools.ietf.org/html/rfc7230#section-3.2.6
const tokenRegExp = /^[\^_`a-zA-Z\-0-9!#$%&'*+.|~]+$/;
const validTokenChars = new Uint8Array([
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0-15
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16-31
0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, // 32-47 (!"#$%&'()*+,-./)
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, // 48-63 (0-9:;<=>?)
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 64-79 (@A-O)
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, // 80-95 (P-Z[\]^_)
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 96-111 (`a-o)
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, // 112-127 (p-z{|}~)
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 128-143
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 144-159
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 160-175
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 176-191
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 192-207
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 208-223
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 224-239
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 240-255
]);
/**
* Verifies that the given val is a valid HTTP token
* per the rules defined in RFC 7230
@ -214,7 +238,19 @@ const tokenRegExp = /^[\^_`a-zA-Z\-0-9!#$%&'*+.|~]+$/;
* @returns {boolean}
*/
function checkIsHttpToken(val) {
return tokenRegExp.test(val);
if (val.length >= 10) {
return tokenRegExp.test(val);
}
if (val.length === 0) return false;
// Use lookup table for short strings, regex for longer ones
for (let i = 0; i < val.length; i++) {
if (!validTokenChars[val.charCodeAt(i)]) {
return false;
}
}
return true;
}
const headerCharRegex = /[^\t\x20-\x7e\x80-\xff]/;