@@ -278,8 +278,19 @@ function updateOptionsBuffer(options) {
278278 optionsBuffer [ IDX_OPTIONS_FLAGS ] = flags ;
279279}
280280
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+
281291function getDefaultSettings ( ) {
282292 settingsBuffer [ IDX_SETTINGS_FLAGS ] = 0 ;
293+ settingsBuffer [ IDX_SETTINGS_FLAGS + 1 ] = 0 ; // Length of custom settings
283294 binding . refreshDefaultSettings ( ) ;
284295 const holder = { __proto__ : null } ;
285296
@@ -327,6 +338,8 @@ function getDefaultSettings() {
327338 settingsBuffer [ IDX_SETTINGS_ENABLE_CONNECT_PROTOCOL ] === 1 ;
328339 }
329340
341+ if ( settingsBuffer [ IDX_SETTINGS_FLAGS + 1 ] ) holder . customSettings = addCustomSettingsToObj ( ) ;
342+
330343 return holder ;
331344}
332345
@@ -338,7 +351,7 @@ function getSettings(session, remote) {
338351 else
339352 session . localSettings ( ) ;
340353
341- return {
354+ const toRet = {
342355 headerTableSize : settingsBuffer [ IDX_SETTINGS_HEADER_TABLE_SIZE ] ,
343356 enablePush : ! ! settingsBuffer [ IDX_SETTINGS_ENABLE_PUSH ] ,
344357 initialWindowSize : settingsBuffer [ IDX_SETTINGS_INITIAL_WINDOW_SIZE ] ,
@@ -349,6 +362,8 @@ function getSettings(session, remote) {
349362 enableConnectProtocol :
350363 ! ! settingsBuffer [ IDX_SETTINGS_ENABLE_CONNECT_PROTOCOL ] ,
351364 } ;
365+ if ( settingsBuffer [ IDX_SETTINGS_FLAGS + 1 ] ) toRet . customSettings = addCustomSettingsToObj ( ) ;
366+ return toRet ;
352367}
353368
354369function updateSettingsBuffer ( settings ) {
@@ -415,12 +430,22 @@ function updateSettingsBuffer(settings) {
415430 }
416431 }
417432 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 ( ) ;
420444
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+ }
424449 }
425450 }
426451 }
@@ -475,6 +500,24 @@ function updateSettingsBuffer(settings) {
475500 settingsBuffer [ IDX_SETTINGS_FLAGS ] = flags ;
476501}
477502
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+
478521function getSessionState ( session ) {
479522 session . refreshState ( ) ;
480523 return {
@@ -649,6 +692,14 @@ const assertIsObject = hideStackFrames((value, name, types) => {
649692 }
650693} ) ;
651694
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+
652703const assertWithinRange = hideStackFrames (
653704 ( name , value , min = 0 , max = Infinity ) => {
654705 if ( value !== undefined &&
@@ -732,6 +783,7 @@ function getAuthority(headers) {
732783
733784module . exports = {
734785 assertIsObject,
786+ assertIsArray,
735787 assertValidPseudoHeader,
736788 assertValidPseudoHeaderResponse,
737789 assertValidPseudoHeaderTrailer,
@@ -747,7 +799,9 @@ module.exports = {
747799 kProxySocket,
748800 kRequest,
749801 mapToHeaders,
802+ MAX_ADDITIONAL_SETTINGS ,
750803 NghttpError,
804+ remoteCustomSettingsToBuffer,
751805 sessionName,
752806 toHeaderObject,
753807 updateOptionsBuffer,
0 commit comments