8
8
Error,
9
9
MathMax,
10
10
Number,
11
+ NumberIsNaN,
11
12
ObjectDefineProperty,
12
13
ObjectKeys,
13
14
SafeSet,
@@ -25,6 +26,7 @@ const {
25
26
ERR_HTTP2_INVALID_CONNECTION_HEADERS ,
26
27
ERR_HTTP2_INVALID_PSEUDOHEADER ,
27
28
ERR_HTTP2_INVALID_SETTING_VALUE ,
29
+ ERR_HTTP2_TOO_MANY_CUSTOM_SETTINGS ,
28
30
ERR_INVALID_ARG_TYPE ,
29
31
ERR_INVALID_HTTP_TOKEN ,
30
32
} ,
@@ -192,6 +194,9 @@ const IDX_SETTINGS_MAX_HEADER_LIST_SIZE = 5;
192
194
const IDX_SETTINGS_ENABLE_CONNECT_PROTOCOL = 6 ;
193
195
const IDX_SETTINGS_FLAGS = 7 ;
194
196
197
+ // Maximum number of allowed additional settings
198
+ const MAX_ADDITIONAL_SETTINGS = 10 ;
199
+
195
200
const IDX_SESSION_STATE_EFFECTIVE_LOCAL_WINDOW_SIZE = 0 ;
196
201
const IDX_SESSION_STATE_EFFECTIVE_RECV_DATA_LENGTH = 1 ;
197
202
const IDX_SESSION_STATE_NEXT_STREAM_ID = 2 ;
@@ -350,6 +355,80 @@ function getSettings(session, remote) {
350
355
351
356
function updateSettingsBuffer ( settings ) {
352
357
let flags = 0 ;
358
+ let numCustomSettings = 0 ;
359
+
360
+ if ( typeof settings . customSettings === 'object' ) {
361
+ const customSettings = settings . customSettings ;
362
+ for ( const setting in customSettings ) {
363
+ const val = customSettings [ setting ] ;
364
+ if ( typeof val === 'number' ) {
365
+ let set = false ;
366
+ const nsetting = Number ( setting ) ;
367
+ if ( NumberIsNaN ( nsetting ) ||
368
+ typeof nsetting !== 'number' ||
369
+ 0 >= nsetting ||
370
+ nsetting > 0xffff )
371
+ throw new ERR_HTTP2_INVALID_SETTING_VALUE . RangeError (
372
+ 'Range Error' , nsetting , 0 , 0xffff ) ;
373
+ if ( NumberIsNaN ( val ) ||
374
+ typeof val !== 'number' ||
375
+ 0 >= val ||
376
+ val > 0xffffffff )
377
+ throw new ERR_HTTP2_INVALID_SETTING_VALUE . RangeError (
378
+ 'Range Error' , val , 0 , 0xffffffff ) ;
379
+ if ( nsetting < IDX_SETTINGS_FLAGS ) {
380
+ set = true ;
381
+ switch ( nsetting ) {
382
+ case IDX_SETTINGS_HEADER_TABLE_SIZE :
383
+ flags |= ( 1 << IDX_SETTINGS_HEADER_TABLE_SIZE ) ;
384
+ settingsBuffer [ IDX_SETTINGS_HEADER_TABLE_SIZE ] =
385
+ val ;
386
+ break ;
387
+ case IDX_SETTINGS_ENABLE_PUSH :
388
+ flags |= ( 1 << IDX_SETTINGS_ENABLE_PUSH ) ;
389
+ settingsBuffer [ IDX_SETTINGS_ENABLE_PUSH ] = val ;
390
+ break ;
391
+ case IDX_SETTINGS_INITIAL_WINDOW_SIZE :
392
+ flags |= ( 1 << IDX_SETTINGS_INITIAL_WINDOW_SIZE ) ;
393
+ settingsBuffer [ IDX_SETTINGS_INITIAL_WINDOW_SIZE ] =
394
+ val ;
395
+ break ;
396
+ case IDX_SETTINGS_MAX_FRAME_SIZE :
397
+ flags |= ( 1 << IDX_SETTINGS_MAX_FRAME_SIZE ) ;
398
+ settingsBuffer [ IDX_SETTINGS_MAX_FRAME_SIZE ] =
399
+ val ;
400
+ break ;
401
+ case IDX_SETTINGS_MAX_CONCURRENT_STREAMS :
402
+ flags |= ( 1 << IDX_SETTINGS_MAX_CONCURRENT_STREAMS ) ;
403
+ settingsBuffer [ IDX_SETTINGS_MAX_CONCURRENT_STREAMS ] = val ;
404
+ break ;
405
+ case IDX_SETTINGS_MAX_HEADER_LIST_SIZE :
406
+ flags |= ( 1 << IDX_SETTINGS_MAX_HEADER_LIST_SIZE ) ;
407
+ settingsBuffer [ IDX_SETTINGS_MAX_HEADER_LIST_SIZE ] =
408
+ val ;
409
+ break ;
410
+ case IDX_SETTINGS_ENABLE_CONNECT_PROTOCOL :
411
+ flags |= ( 1 << IDX_SETTINGS_ENABLE_CONNECT_PROTOCOL ) ;
412
+ settingsBuffer [ IDX_SETTINGS_ENABLE_CONNECT_PROTOCOL ] = val ;
413
+ break ;
414
+ default :
415
+ set = false ;
416
+ break ;
417
+ }
418
+ }
419
+ if ( ! set ) { // not supported
420
+ if ( numCustomSettings === MAX_ADDITIONAL_SETTINGS )
421
+ throw new ERR_HTTP2_TOO_MANY_CUSTOM_SETTINGS ( ) ;
422
+
423
+ settingsBuffer [ IDX_SETTINGS_FLAGS + 1 + 2 * numCustomSettings + 1 ] = nsetting ;
424
+ settingsBuffer [ IDX_SETTINGS_FLAGS + 1 + 2 * numCustomSettings + 2 ] = val ;
425
+ numCustomSettings ++ ;
426
+ }
427
+ }
428
+ }
429
+ }
430
+ settingsBuffer [ IDX_SETTINGS_FLAGS + 1 ] = numCustomSettings ;
431
+
353
432
if ( typeof settings . headerTableSize === 'number' ) {
354
433
flags |= ( 1 << IDX_SETTINGS_HEADER_TABLE_SIZE ) ;
355
434
settingsBuffer [ IDX_SETTINGS_HEADER_TABLE_SIZE ] =
0 commit comments