File tree 2 files changed +100
-2
lines changed
2 files changed +100
-2
lines changed Original file line number Diff line number Diff line change
1
+ 'use strict' ;
2
+
3
+ const common = require ( '../common.js' ) ;
4
+ const _checkIsHttpToken = require ( '_http_common' ) . _checkIsHttpToken ;
5
+
6
+ const bench = common . createBenchmark ( main , {
7
+ key : [
8
+ 'TCN' ,
9
+ 'ETag' ,
10
+ 'date' ,
11
+ 'Vary' ,
12
+ 'server' ,
13
+ 'Server' ,
14
+ 'status' ,
15
+ 'version' ,
16
+ 'Expires' ,
17
+ 'alt-svc' ,
18
+ 'location' ,
19
+ 'Connection' ,
20
+ 'Keep-Alive' ,
21
+ 'content-type' ,
22
+ 'Content-Type' ,
23
+ 'Cache-Control' ,
24
+ 'Last-Modified' ,
25
+ 'Accept-Ranges' ,
26
+ 'content-length' ,
27
+ 'x-frame-options' ,
28
+ 'x-xss-protection' ,
29
+ 'Content-Encoding' ,
30
+ 'Content-Location' ,
31
+ 'Transfer-Encoding' ,
32
+ 'alternate-protocol' ,
33
+ ':' , // invalid input
34
+ '@@' ,
35
+ '中文呢' , // unicode
36
+ '((((())))' , // invalid
37
+ ':alternate-protocol' , // fast bailout
38
+ 'alternate-protocol:' // slow bailout
39
+ ] ,
40
+ n : [ 1e6 ] ,
41
+ } ) ;
42
+
43
+ function main ( conf ) {
44
+ var n = + conf . n ;
45
+ var key = conf . key ;
46
+
47
+ bench . start ( ) ;
48
+ for ( var i = 0 ; i < n ; i ++ ) {
49
+ _checkIsHttpToken ( key ) ;
50
+ }
51
+ bench . end ( n ) ;
52
+ }
Original file line number Diff line number Diff line change @@ -225,10 +225,56 @@ exports.httpSocketSetup = httpSocketSetup;
225
225
/**
226
226
* Verifies that the given val is a valid HTTP token
227
227
* per the rules defined in RFC 7230
228
+ * See https://tools.ietf.org/html/rfc7230#section-3.2.6
229
+ *
230
+ * This implementation of checkIsHttpToken() loops over the string instead of
231
+ * using a regular expression since the former is up to 180% faster with v8 4.9
232
+ * depending on the string length (the shorter the string, the larger the
233
+ * performance difference)
228
234
**/
229
- const token = / ^ [ a - z A - Z 0 - 9 _ ! # $ % & ' * + . ^ ` | ~ - ] + $ / ;
230
235
function checkIsHttpToken ( val ) {
231
- return typeof val === 'string' && token . test ( val ) ;
236
+ if ( typeof val !== 'string' || val . length === 0 )
237
+ return false ;
238
+
239
+ for ( var i = 0 , len = val . length ; i < len ; i ++ ) {
240
+ var ch = val . charCodeAt ( i ) ;
241
+
242
+ if ( ch >= 65 && ch <= 90 ) // A-Z
243
+ continue ;
244
+
245
+ if ( ch >= 97 && ch <= 122 ) // a-z
246
+ continue ;
247
+
248
+ // ^ => 94
249
+ // _ => 95
250
+ // ` => 96
251
+ // | => 124
252
+ // ~ => 126
253
+ if ( ch === 94 || ch === 95 || ch === 96 || ch === 124 || ch === 126 )
254
+ continue ;
255
+
256
+ if ( ch >= 48 && ch <= 57 ) // 0-9
257
+ continue ;
258
+
259
+ // ! => 33
260
+ // # => 35
261
+ // $ => 36
262
+ // % => 37
263
+ // & => 38
264
+ // ' => 39
265
+ // * => 42
266
+ // + => 43
267
+ // - => 45
268
+ // . => 46
269
+ if ( ch >= 33 && ch <= 46 ) {
270
+ if ( ch === 34 || ch === 40 || ch === 41 || ch === 44 )
271
+ return false ;
272
+ continue ;
273
+ }
274
+
275
+ return false ;
276
+ }
277
+ return true ;
232
278
}
233
279
exports . _checkIsHttpToken = checkIsHttpToken ;
234
280
You can’t perform that action at this time.
0 commit comments