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