@@ -278,8 +278,19 @@ function updateOptionsBuffer(options) {
278
278
optionsBuffer [ IDX_OPTIONS_FLAGS ] = flags ;
279
279
}
280
280
281
+ function addCustomSettingsToObj ( ) {
282
+ const toRet = { } ;
283
+ const num = settingsBuffer [ IDX_SETTINGS_FLAGS + 1 ] ;
284
+ for ( let i = 0 ; i < num ; i ++ ) {
285
+ toRet [ settingsBuffer [ IDX_SETTINGS_FLAGS + 1 + 2 * i + 1 ] . toString ( ) ] =
286
+ Number ( settingsBuffer [ IDX_SETTINGS_FLAGS + 1 + 2 * i + 2 ] ) ;
287
+ }
288
+ return toRet ;
289
+ }
290
+
281
291
function getDefaultSettings ( ) {
282
292
settingsBuffer [ IDX_SETTINGS_FLAGS ] = 0 ;
293
+ settingsBuffer [ IDX_SETTINGS_FLAGS + 1 ] = 0 ; // Length of custom settings
283
294
binding . refreshDefaultSettings ( ) ;
284
295
const holder = { __proto__ : null } ;
285
296
@@ -327,6 +338,8 @@ function getDefaultSettings() {
327
338
settingsBuffer [ IDX_SETTINGS_ENABLE_CONNECT_PROTOCOL ] === 1 ;
328
339
}
329
340
341
+ if ( settingsBuffer [ IDX_SETTINGS_FLAGS + 1 ] ) holder . customSettings = addCustomSettingsToObj ( ) ;
342
+
330
343
return holder ;
331
344
}
332
345
@@ -338,7 +351,7 @@ function getSettings(session, remote) {
338
351
else
339
352
session . localSettings ( ) ;
340
353
341
- return {
354
+ const toRet = {
342
355
headerTableSize : settingsBuffer [ IDX_SETTINGS_HEADER_TABLE_SIZE ] ,
343
356
enablePush : ! ! settingsBuffer [ IDX_SETTINGS_ENABLE_PUSH ] ,
344
357
initialWindowSize : settingsBuffer [ IDX_SETTINGS_INITIAL_WINDOW_SIZE ] ,
@@ -349,6 +362,8 @@ function getSettings(session, remote) {
349
362
enableConnectProtocol :
350
363
! ! settingsBuffer [ IDX_SETTINGS_ENABLE_CONNECT_PROTOCOL ] ,
351
364
} ;
365
+ if ( settingsBuffer [ IDX_SETTINGS_FLAGS + 1 ] ) toRet . customSettings = addCustomSettingsToObj ( ) ;
366
+ return toRet ;
352
367
}
353
368
354
369
function updateSettingsBuffer ( settings ) {
@@ -415,12 +430,22 @@ function updateSettingsBuffer(settings) {
415
430
}
416
431
}
417
432
if ( ! set ) { // not supported
418
- if ( numCustomSettings === MAX_ADDITIONAL_SETTINGS )
419
- throw new ERR_HTTP2_TOO_MANY_CUSTOM_SETTINGS ( ) ;
433
+ let i = 0 ;
434
+ while ( i < numCustomSettings ) {
435
+ if ( settingsBuffer [ IDX_SETTINGS_FLAGS + 1 + 2 * i + 1 ] === nsetting ) {
436
+ settingsBuffer [ IDX_SETTINGS_FLAGS + 1 + 2 * i + 2 ] = val ;
437
+ break ;
438
+ }
439
+ i ++ ;
440
+ }
441
+ if ( i === numCustomSettings ) {
442
+ if ( numCustomSettings === MAX_ADDITIONAL_SETTINGS )
443
+ throw new ERR_HTTP2_TOO_MANY_CUSTOM_SETTINGS ( ) ;
420
444
421
- settingsBuffer [ IDX_SETTINGS_FLAGS + 1 + 2 * numCustomSettings + 1 ] = nsetting ;
422
- settingsBuffer [ IDX_SETTINGS_FLAGS + 1 + 2 * numCustomSettings + 2 ] = val ;
423
- numCustomSettings ++ ;
445
+ settingsBuffer [ IDX_SETTINGS_FLAGS + 1 + 2 * numCustomSettings + 1 ] = nsetting ;
446
+ settingsBuffer [ IDX_SETTINGS_FLAGS + 1 + 2 * numCustomSettings + 2 ] = val ;
447
+ numCustomSettings ++ ;
448
+ }
424
449
}
425
450
}
426
451
}
@@ -475,6 +500,24 @@ function updateSettingsBuffer(settings) {
475
500
settingsBuffer [ IDX_SETTINGS_FLAGS ] = flags ;
476
501
}
477
502
503
+ function remoteCustomSettingsToBuffer ( remoteCustomSettings ) {
504
+ if ( remoteCustomSettings . length > MAX_ADDITIONAL_SETTINGS )
505
+ throw new ERR_HTTP2_TOO_MANY_CUSTOM_SETTINGS ( ) ;
506
+ let numCustomSettings = 0 ;
507
+ for ( let i = 0 ; i < remoteCustomSettings . length ; i ++ ) {
508
+ const nsetting = remoteCustomSettings [ i ] ;
509
+ if ( typeof nsetting === 'number' && nsetting <= 0xffff &&
510
+ nsetting >= 0 ) {
511
+ settingsBuffer [ IDX_SETTINGS_FLAGS + 1 + 2 * numCustomSettings + 1 ] = nsetting ;
512
+ numCustomSettings ++ ;
513
+ } else
514
+ throw new ERR_HTTP2_INVALID_SETTING_VALUE . RangeError (
515
+ 'Range Error' , nsetting , 0 , 0xffff ) ;
516
+
517
+ }
518
+ settingsBuffer [ IDX_SETTINGS_FLAGS + 1 ] = numCustomSettings ;
519
+ }
520
+
478
521
function getSessionState ( session ) {
479
522
session . refreshState ( ) ;
480
523
return {
@@ -649,6 +692,14 @@ const assertIsObject = hideStackFrames((value, name, types) => {
649
692
}
650
693
} ) ;
651
694
695
+ const assertIsArray = hideStackFrames ( ( value , name , types ) => {
696
+ if ( value !== undefined &&
697
+ ( value === null ||
698
+ ! ArrayIsArray ( value ) ) ) {
699
+ throw new ERR_INVALID_ARG_TYPE . HideStackFramesError ( name , types || 'Array' , value ) ;
700
+ }
701
+ } ) ;
702
+
652
703
const assertWithinRange = hideStackFrames (
653
704
( name , value , min = 0 , max = Infinity ) => {
654
705
if ( value !== undefined &&
@@ -732,6 +783,7 @@ function getAuthority(headers) {
732
783
733
784
module . exports = {
734
785
assertIsObject,
786
+ assertIsArray,
735
787
assertValidPseudoHeader,
736
788
assertValidPseudoHeaderResponse,
737
789
assertValidPseudoHeaderTrailer,
@@ -747,7 +799,9 @@ module.exports = {
747
799
kProxySocket,
748
800
kRequest,
749
801
mapToHeaders,
802
+ MAX_ADDITIONAL_SETTINGS ,
750
803
NghttpError,
804
+ remoteCustomSettingsToBuffer,
751
805
sessionName,
752
806
toHeaderObject,
753
807
updateOptionsBuffer,
0 commit comments