GeezerVison is showing github.com — http: optimize checkIsHttpToken for short strings · nodejs/node@758271a
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: lib/_http_common.js +37-1Lines changed: 37 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
| 24 | 24 | const { | 25 | 25 | MathMin, | 26 | 26 | Symbol, | | 27 | + Uint8Array, | 27 | 28 | } = primordials; | 28 | 29 | const { setImmediate } = require('timers'); | 29 | 30 |
| @@ -205,14 +206,49 @@ function freeParser(parser, req, socket) { | 205 | 206 | } | 206 | 207 | } | 207 | 208 |
| | 209 | +// Character code ranges for valid HTTP tokens | | 210 | +// Valid chars: ^_`a-zA-Z-0-9!#$%&'*+.|~ | | 211 | +// Based on RFC 7230 Section 3.2.6 token definition | | 212 | +// See https://tools.ietf.org/html/rfc7230#section-3.2.6 | 208 | 213 | const tokenRegExp = /^[\^_`a-zA-Z\-0-9!#$%&'*+.|~]+$/; | | 214 | +const validTokenChars = new Uint8Array([ | | 215 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0-15 | | 216 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16-31 | | 217 | + 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, // 32-47 (!"#$%&'()*+,-./) | | 218 | + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, // 48-63 (0-9:;<=>?) | | 219 | + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 64-79 (@A-O) | | 220 | + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, // 80-95 (P-Z[\]^_) | | 221 | + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 96-111 (`a-o) | | 222 | + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, // 112-127 (p-z{|}~) | | 223 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 128-143 | | 224 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 144-159 | | 225 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 160-175 | | 226 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 176-191 | | 227 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 192-207 | | 228 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 208-223 | | 229 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 224-239 | | 230 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 240-255 | | 231 | +]); | | 232 | + | 209 | 233 | /** | 210 | 234 | * Verifies that the given val is a valid HTTP token | 211 | 235 | * per the rules defined in RFC 7230 | 212 | 236 | * See https://tools.ietf.org/html/rfc7230#section-3.2.6 | 213 | 237 | */ | 214 | 238 | function checkIsHttpToken(val) { | 215 | | - return tokenRegExp.test(val); | | 239 | + if (val.length >= 10) { | | 240 | + return tokenRegExp.test(val); | | 241 | + } | | 242 | + | | 243 | + if (val.length === 0) return false; | | 244 | + | | 245 | + // Use lookup table for short strings, regex for longer ones | | 246 | + for (let i = 0; i < val.length; i++) { | | 247 | + if (!validTokenChars[val.charCodeAt(i)]) { | | 248 | + return false; | | 249 | + } | | 250 | + } | | 251 | + return true; | 216 | 252 | } | 217 | 253 |
| 218 | 254 | const headerCharRegex = /[^\t\x20-\x7e\x80-\xff]/; | |
|