Skip to content

Commit

Permalink
http: improve validation performance
Browse files Browse the repository at this point in the history
The new table-based lookups perform significantly better for the
common cases (checking latin1 characters).

PR-URL: #6533
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
  • Loading branch information
mscdex authored and evanlucas committed Jan 4, 2017
1 parent df8b8b2 commit 8a2a763
Showing 1 changed file with 59 additions and 41 deletions.
100 changes: 59 additions & 41 deletions lib/_http_common.js
Original file line number Diff line number Diff line change
Expand Up @@ -246,44 +246,44 @@ exports.httpSocketSetup = httpSocketSetup;
* so take care when making changes to the implementation so that the source
* code size does not exceed v8's default max_inlined_source_size setting.
**/
function isValidTokenChar(ch) {
if (ch >= 94 && ch <= 122)
return true;
if (ch >= 65 && ch <= 90)
return true;
if (ch === 45)
return true;
if (ch >= 48 && ch <= 57)
return true;
if (ch === 34 || ch === 40 || ch === 41 || ch === 44)
var validTokens = [
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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 64 - 79
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, // 80 - 95
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 96 - 111
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, // 112 - 127
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 128 ...
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // ... 255
];
function checkIsHttpToken(val) {
if (typeof val !== 'string' || val.length === 0)
return false;
if (!validTokens[val.charCodeAt(0)])
return false;
if (ch >= 33 && ch <= 46)
if (val.length < 2)
return true;
if (ch === 124 || ch === 126)
if (!validTokens[val.charCodeAt(1)])
return false;
if (val.length < 3)
return true;
return false;
}
function checkIsHttpToken(val) {
if (typeof val !== 'string' || val.length === 0)
if (!validTokens[val.charCodeAt(2)])
return false;
if (!isValidTokenChar(val.charCodeAt(0)))
if (val.length < 4)
return true;
if (!validTokens[val.charCodeAt(3)])
return false;
const len = val.length;
if (len > 1) {
if (!isValidTokenChar(val.charCodeAt(1)))
for (var i = 4; i < val.length; ++i) {
if (!validTokens[val.charCodeAt(i)])
return false;
if (len > 2) {
if (!isValidTokenChar(val.charCodeAt(2)))
return false;
if (len > 3) {
if (!isValidTokenChar(val.charCodeAt(3)))
return false;
for (var i = 4; i < len; i++) {
if (!isValidTokenChar(val.charCodeAt(i)))
return false;
}
}
}
}
return true;
}
Expand All @@ -299,26 +299,44 @@ exports._checkIsHttpToken = checkIsHttpToken;
* so take care when making changes to the implementation so that the source
* code size does not exceed v8's default max_inlined_source_size setting.
**/
var validHdrChars = [
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 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
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 32 - 47
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 48 - 63
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 64 - 79
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 80 - 95
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 96 - 111
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, // 112 - 127
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 128 ...
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // ... 255
];
function checkInvalidHeaderChar(val) {
val += '';
if (val.length < 1)
return false;
var c = val.charCodeAt(0);
if ((c <= 31 && c !== 9) || c > 255 || c === 127)
if (!validHdrChars[val.charCodeAt(0)])
return true;
if (val.length < 2)
return false;
c = val.charCodeAt(1);
if ((c <= 31 && c !== 9) || c > 255 || c === 127)
if (!validHdrChars[val.charCodeAt(1)])
return true;
if (val.length < 3)
return false;
c = val.charCodeAt(2);
if ((c <= 31 && c !== 9) || c > 255 || c === 127)
if (!validHdrChars[val.charCodeAt(2)])
return true;
if (val.length < 4)
return false;
if (!validHdrChars[val.charCodeAt(3)])
return true;
for (var i = 3; i < val.length; ++i) {
c = val.charCodeAt(i);
if ((c <= 31 && c !== 9) || c > 255 || c === 127)
for (var i = 4; i < val.length; ++i) {
if (!validHdrChars[val.charCodeAt(i)])
return true;
}
return false;
Expand Down

0 comments on commit 8a2a763

Please sign in to comment.