http: optimize checkIsHttpToken for short strings · nodejs/node@83ae610

@@ -24,6 +24,7 @@

2424

const {

2525

MathMin,

2626

Symbol,

27+

Uint8Array,

2728

} = primordials;

2829

const { setImmediate } = require('timers');

2930

@@ -205,7 +206,30 @@ function freeParser(parser, req, socket) {

205206

}

206207

}

207208209+

// 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

208213

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+209233

/**

210234

* Verifies that the given val is a valid HTTP token

211235

* per the rules defined in RFC 7230

@@ -214,7 +238,19 @@ const tokenRegExp = /^[\^_`a-zA-Z\-0-9!#$%&'*+.|~]+$/;

214238

* @returns {boolean}

215239

*/

216240

function checkIsHttpToken(val) {

217-

return tokenRegExp.test(val);

241+

if (val.length >= 10) {

242+

return tokenRegExp.test(val);

243+

}

244+245+

if (val.length === 0) return false;

246+247+

// Use lookup table for short strings, regex for longer ones

248+

for (let i = 0; i < val.length; i++) {

249+

if (!validTokenChars[val.charCodeAt(i)]) {

250+

return false;

251+

}

252+

}

253+

return true;

218254

}

219255220256

const headerCharRegex = /[^\t\x20-\x7e\x80-\xff]/;