@@ -232,52 +232,65 @@ exports.httpSocketSetup = httpSocketSetup;
232
232
* per the rules defined in RFC 7230
233
233
* See https://tools.ietf.org/html/rfc7230#section-3.2.6
234
234
*
235
+ * Allowed characters in an HTTP token:
236
+ * ^_`a-z 94-122
237
+ * A-Z 65-90
238
+ * - 45
239
+ * 0-9 48-57
240
+ * ! 33
241
+ * #$%&' 35-39
242
+ * *+ 42-43
243
+ * . 46
244
+ * | 124
245
+ * ~ 126
246
+ *
235
247
* This implementation of checkIsHttpToken() loops over the string instead of
236
248
* using a regular expression since the former is up to 180% faster with v8 4.9
237
249
* depending on the string length (the shorter the string, the larger the
238
250
* performance difference)
251
+ *
252
+ * Additionally, checkIsHttpToken() is currently designed to be inlinable by v8,
253
+ * so take care when making changes to the implementation so that the source
254
+ * code size does not exceed v8's default max_inlined_source_size setting.
239
255
**/
256
+ function isValidTokenChar ( ch ) {
257
+ if ( ch >= 94 && ch <= 122 )
258
+ return true ;
259
+ if ( ch >= 65 && ch <= 90 )
260
+ return true ;
261
+ if ( ch === 45 )
262
+ return true ;
263
+ if ( ch >= 48 && ch <= 57 )
264
+ return true ;
265
+ if ( ch === 34 || ch === 40 || ch === 41 || ch === 44 )
266
+ return false ;
267
+ if ( ch >= 33 && ch <= 46 )
268
+ return true ;
269
+ if ( ch === 124 || ch === 126 )
270
+ return true ;
271
+ return false ;
272
+ }
240
273
function checkIsHttpToken ( val ) {
241
274
if ( typeof val !== 'string' || val . length === 0 )
242
275
return false ;
243
-
244
- for ( var i = 0 , len = val . length ; i < len ; i ++ ) {
245
- var ch = val . charCodeAt ( i ) ;
246
-
247
- if ( ch >= 65 && ch <= 90 ) // A-Z
248
- continue ;
249
-
250
- if ( ch >= 97 && ch <= 122 ) // a-z
251
- continue ;
252
-
253
- // ^ => 94
254
- // _ => 95
255
- // ` => 96
256
- // | => 124
257
- // ~ => 126
258
- if ( ch === 94 || ch === 95 || ch === 96 || ch === 124 || ch === 126 )
259
- continue ;
260
-
261
- if ( ch >= 48 && ch <= 57 ) // 0-9
262
- continue ;
263
-
264
- // ! => 33
265
- // # => 35
266
- // $ => 36
267
- // % => 37
268
- // & => 38
269
- // ' => 39
270
- // * => 42
271
- // + => 43
272
- // - => 45
273
- // . => 46
274
- if ( ch >= 33 && ch <= 46 ) {
275
- if ( ch === 34 || ch === 40 || ch === 41 || ch === 44 )
276
+ if ( ! isValidTokenChar ( val . charCodeAt ( 0 ) ) )
277
+ return false ;
278
+ const len = val . length ;
279
+ if ( len > 1 ) {
280
+ if ( ! isValidTokenChar ( val . charCodeAt ( 1 ) ) )
281
+ return false ;
282
+ if ( len > 2 ) {
283
+ if ( ! isValidTokenChar ( val . charCodeAt ( 2 ) ) )
276
284
return false ;
277
- continue ;
285
+ if ( len > 3 ) {
286
+ if ( ! isValidTokenChar ( val . charCodeAt ( 3 ) ) )
287
+ return false ;
288
+ for ( var i = 4 ; i < len ; i ++ ) {
289
+ if ( ! isValidTokenChar ( val . charCodeAt ( i ) ) )
290
+ return false ;
291
+ }
292
+ }
278
293
}
279
-
280
- return false ;
281
294
}
282
295
return true ;
283
296
}
0 commit comments