summaryrefslogtreecommitdiff
path: root/lib/_http_common.js
diff options
context:
space:
mode:
authorBrian White <mscdex@mscdex.net>2016-12-18 21:21:57 -0500
committerBrian White <mscdex@mscdex.net>2016-12-29 14:19:00 -0500
commita54972c195f708afbd985d981b804834817da92b (patch)
treefcadf2dffea460bc03c9938fc256fc12f3c1d35c /lib/_http_common.js
parent832271c88f7950678595de1a329f4033e937a24e (diff)
downloadnode-new-a54972c195f708afbd985d981b804834817da92b.tar.gz
http: improve validation performance
The new table-based lookups perform significantly better for the common cases (checking latin1 characters). PR-URL: https://github.com/nodejs/node/pull/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>
Diffstat (limited to 'lib/_http_common.js')
-rw-r--r--lib/_http_common.js100
1 files changed, 59 insertions, 41 deletions
diff --git a/lib/_http_common.js b/lib/_http_common.js
index b0767fd43c..2ce523fe62 100644
--- a/lib/_http_common.js
+++ b/lib/_http_common.js
@@ -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;
}
@@ -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;