99 ObjectDefineProperty,
1010 ObjectEntries,
1111 ObjectHasOwn,
12- ObjectKeys,
1312 Promise,
1413 Proxy,
1514 ReflectApply,
@@ -47,10 +46,7 @@ const { Duplex } = require('stream');
4746const tls = require ( 'tls' ) ;
4847const { setImmediate, setTimeout, clearTimeout } = require ( 'timers' ) ;
4948
50- const {
51- kIncomingMessage,
52- _checkIsHttpToken : checkIsHttpToken ,
53- } = require ( '_http_common' ) ;
49+ const { kIncomingMessage } = require ( '_http_common' ) ;
5450const { kServerResponse, Server : HttpServer , httpServerPreClose, setupConnectionsTracking } = require ( '_http_server' ) ;
5551const JSStreamSocket = require ( 'internal/js_stream_socket' ) ;
5652
@@ -69,9 +65,6 @@ const {
6965 codes : {
7066 ERR_HTTP2_ALTSVC_INVALID_ORIGIN ,
7167 ERR_HTTP2_ALTSVC_LENGTH ,
72- ERR_HTTP2_CONNECT_AUTHORITY ,
73- ERR_HTTP2_CONNECT_PATH ,
74- ERR_HTTP2_CONNECT_SCHEME ,
7568 ERR_HTTP2_GOAWAY_SESSION ,
7669 ERR_HTTP2_HEADERS_AFTER_RESPOND ,
7770 ERR_HTTP2_HEADERS_SENT ,
@@ -109,7 +102,6 @@ const {
109102 ERR_INVALID_ARG_TYPE ,
110103 ERR_INVALID_ARG_VALUE ,
111104 ERR_INVALID_CHAR ,
112- ERR_INVALID_HTTP_TOKEN ,
113105 ERR_OUT_OF_RANGE ,
114106 ERR_SOCKET_CLOSED ,
115107 } ,
@@ -138,23 +130,26 @@ const {
138130const {
139131 assertIsObject,
140132 assertIsArray,
141- assertValidPseudoHeader,
142133 assertValidPseudoHeaderResponse,
143134 assertValidPseudoHeaderTrailer,
144135 assertWithinRange,
136+ buildNgHeaderString,
145137 getAuthority,
146138 getDefaultSettings,
147139 getSessionState,
148140 getSettings,
149141 getStreamState,
150142 isPayloadMeaningless,
143+ kAuthority,
151144 kSensitiveHeaders,
152145 kSocket,
153146 kRequest,
147+ kProtocol,
154148 kProxySocket,
155- mapToHeaders,
156149 MAX_ADDITIONAL_SETTINGS ,
157150 NghttpError,
151+ prepareRequestHeadersArray,
152+ prepareRequestHeadersObject,
158153 remoteCustomSettingsToBuffer,
159154 sessionName,
160155 toHeaderObject,
@@ -242,7 +237,6 @@ const NETServer = net.Server;
242237const TLSServer = tls . Server ;
243238
244239const kAlpnProtocol = Symbol ( 'alpnProtocol' ) ;
245- const kAuthority = Symbol ( 'authority' ) ;
246240const kEncrypted = Symbol ( 'encrypted' ) ;
247241const kID = Symbol ( 'id' ) ;
248242const kInit = Symbol ( 'init' ) ;
@@ -254,7 +248,6 @@ const kOwner = owner_symbol;
254248const kOrigin = Symbol ( 'origin' ) ;
255249const kPendingRequestCalls = Symbol ( 'kPendingRequestCalls' ) ;
256250const kProceed = Symbol ( 'proceed' ) ;
257- const kProtocol = Symbol ( 'protocol' ) ;
258251const kRemoteSettings = Symbol ( 'remote-settings' ) ;
259252const kRequestAsyncResource = Symbol ( 'requestAsyncResource' ) ;
260253const kSentHeaders = Symbol ( 'sent-headers' ) ;
@@ -297,7 +290,6 @@ const {
297290 HTTP2_HEADER_DATE ,
298291 HTTP2_HEADER_METHOD ,
299292 HTTP2_HEADER_PATH ,
300- HTTP2_HEADER_PROTOCOL ,
301293 HTTP2_HEADER_SCHEME ,
302294 HTTP2_HEADER_STATUS ,
303295 HTTP2_HEADER_CONTENT_LENGTH ,
@@ -312,7 +304,6 @@ const {
312304
313305 HTTP2_METHOD_GET ,
314306 HTTP2_METHOD_HEAD ,
315- HTTP2_METHOD_CONNECT ,
316307
317308 HTTP_STATUS_CONTINUE ,
318309 HTTP_STATUS_RESET_CONTENT ,
@@ -1808,7 +1799,7 @@ class ClientHttp2Session extends Http2Session {
18081799
18091800 // Submits a new HTTP2 request to the connected peer. Returns the
18101801 // associated Http2Stream instance.
1811- request ( headers , options ) {
1802+ request ( headersParam , options ) {
18121803 debugSessionObj ( this , 'initiating request' ) ;
18131804
18141805 if ( this . destroyed )
@@ -1819,62 +1810,61 @@ class ClientHttp2Session extends Http2Session {
18191810
18201811 this [ kUpdateTimer ] ( ) ;
18211812
1822- if ( headers !== null && headers !== undefined ) {
1823- const keys = ObjectKeys ( headers ) ;
1824- for ( let i = 0 ; i < keys . length ; i ++ ) {
1825- const header = keys [ i ] ;
1826- if ( header [ 0 ] === ':' ) {
1827- assertValidPseudoHeader ( header ) ;
1828- } else if ( header && ! checkIsHttpToken ( header ) )
1829- this . destroy ( new ERR_INVALID_HTTP_TOKEN ( 'Header name' , header ) ) ;
1830- }
1813+ let headersList ;
1814+ let headersObject ;
1815+ let scheme ;
1816+ let authority ;
1817+ let method ;
1818+
1819+ if ( ArrayIsArray ( headersParam ) ) {
1820+ ( {
1821+ headersList,
1822+ scheme,
1823+ authority,
1824+ method,
1825+ } = prepareRequestHeadersArray ( headersParam , this ) ) ;
1826+ } else if ( ! ! headersParam && typeof headersParam === 'object' ) {
1827+ ( {
1828+ headersObject,
1829+ headersList,
1830+ scheme,
1831+ authority,
1832+ method,
1833+ } = prepareRequestHeadersObject ( headersParam , this ) ) ;
1834+ } else if ( headersParam === undefined ) {
1835+ ( {
1836+ headersObject,
1837+ headersList,
1838+ scheme,
1839+ authority,
1840+ method,
1841+ } = prepareRequestHeadersObject ( { } , this ) ) ;
1842+ } else {
1843+ throw new ERR_INVALID_ARG_TYPE . HideStackFramesError (
1844+ 'headers' ,
1845+ [ 'Object' , 'Array' ] ,
1846+ headersParam ,
1847+ ) ;
18311848 }
18321849
1833- assertIsObject ( headers , 'headers' ) ;
18341850 assertIsObject ( options , 'options' ) ;
1835-
1836- headers = ObjectAssign ( { __proto__ : null } , headers ) ;
18371851 options = { ...options } ;
18381852
1839- if ( headers [ HTTP2_HEADER_METHOD ] === undefined )
1840- headers [ HTTP2_HEADER_METHOD ] = HTTP2_METHOD_GET ;
1841-
1842- const connect = headers [ HTTP2_HEADER_METHOD ] === HTTP2_METHOD_CONNECT ;
1843-
1844- if ( ! connect || headers [ HTTP2_HEADER_PROTOCOL ] !== undefined ) {
1845- if ( getAuthority ( headers ) === undefined )
1846- headers [ HTTP2_HEADER_AUTHORITY ] = this [ kAuthority ] ;
1847- if ( headers [ HTTP2_HEADER_SCHEME ] === undefined )
1848- headers [ HTTP2_HEADER_SCHEME ] = this [ kProtocol ] . slice ( 0 , - 1 ) ;
1849- if ( headers [ HTTP2_HEADER_PATH ] === undefined )
1850- headers [ HTTP2_HEADER_PATH ] = '/' ;
1851- } else {
1852- if ( headers [ HTTP2_HEADER_AUTHORITY ] === undefined )
1853- throw new ERR_HTTP2_CONNECT_AUTHORITY ( ) ;
1854- if ( headers [ HTTP2_HEADER_SCHEME ] !== undefined )
1855- throw new ERR_HTTP2_CONNECT_SCHEME ( ) ;
1856- if ( headers [ HTTP2_HEADER_PATH ] !== undefined )
1857- throw new ERR_HTTP2_CONNECT_PATH ( ) ;
1858- }
1859-
18601853 setAndValidatePriorityOptions ( options ) ;
18611854
18621855 if ( options . endStream === undefined ) {
18631856 // For some methods, we know that a payload is meaningless, so end the
18641857 // stream by default if the user has not specifically indicated a
18651858 // preference.
1866- options . endStream = isPayloadMeaningless ( headers [ HTTP2_HEADER_METHOD ] ) ;
1859+ options . endStream = isPayloadMeaningless ( method ) ;
18671860 } else {
18681861 validateBoolean ( options . endStream , 'options.endStream' ) ;
18691862 }
18701863
1871- const headersList = mapToHeaders ( headers ) ;
1872-
18731864 // eslint-disable-next-line no-use-before-define
18741865 const stream = new ClientHttp2Stream ( this , undefined , undefined , { } ) ;
1875- stream [ kSentHeaders ] = headers ;
1876- stream [ kOrigin ] = `${ headers [ HTTP2_HEADER_SCHEME ] } ://` +
1877- `${ getAuthority ( headers ) } ` ;
1866+ stream [ kSentHeaders ] = headersObject ; // N.b. Only set for object headers, not raw headers
1867+ stream [ kOrigin ] = `${ scheme } ://${ authority } ` ;
18781868 const reqAsync = new AsyncResource ( 'PendingRequest' ) ;
18791869 stream [ kRequestAsyncResource ] = reqAsync ;
18801870
@@ -2350,7 +2340,7 @@ class Http2Stream extends Duplex {
23502340
23512341 this [ kUpdateTimer ] ( ) ;
23522342
2353- const headersList = mapToHeaders ( headers , assertValidPseudoHeaderTrailer ) ;
2343+ const headersList = buildNgHeaderString ( headers , assertValidPseudoHeaderTrailer ) ;
23542344 this [ kSentTrailers ] = headers ;
23552345
23562346 // Send the trailers in setImmediate so we don't do it on nghttp2 stack.
@@ -2598,7 +2588,7 @@ function processRespondWithFD(self, fd, headers, offset = 0, length = -1,
25982588
25992589 let headersList ;
26002590 try {
2601- headersList = mapToHeaders ( headers , assertValidPseudoHeaderResponse ) ;
2591+ headersList = buildNgHeaderString ( headers , assertValidPseudoHeaderResponse ) ;
26022592 } catch ( err ) {
26032593 self . destroy ( err ) ;
26042594 return ;
@@ -2822,7 +2812,7 @@ class ServerHttp2Stream extends Http2Stream {
28222812 if ( headers [ HTTP2_HEADER_METHOD ] === HTTP2_METHOD_HEAD )
28232813 headRequest = options . endStream = true ;
28242814
2825- const headersList = mapToHeaders ( headers ) ;
2815+ const headersList = buildNgHeaderString ( headers ) ;
28262816
28272817 const streamOptions = options . endStream ? STREAM_OPTION_EMPTY_PAYLOAD : 0 ;
28282818
@@ -2902,7 +2892,7 @@ class ServerHttp2Stream extends Http2Stream {
29022892 }
29032893
29042894 headers = processHeaders ( headers , options ) ;
2905- const headersList = mapToHeaders ( headers , assertValidPseudoHeaderResponse ) ;
2895+ const headersList = buildNgHeaderString ( headers , assertValidPseudoHeaderResponse ) ;
29062896 this [ kSentHeaders ] = headers ;
29072897
29082898 state . flags |= STREAM_FLAGS_HEADERS_SENT ;
@@ -3079,7 +3069,7 @@ class ServerHttp2Stream extends Http2Stream {
30793069
30803070 this [ kUpdateTimer ] ( ) ;
30813071
3082- const headersList = mapToHeaders ( headers , assertValidPseudoHeaderResponse ) ;
3072+ const headersList = buildNgHeaderString ( headers , assertValidPseudoHeaderResponse ) ;
30833073 if ( ! this [ kInfoHeaders ] )
30843074 this [ kInfoHeaders ] = [ headers ] ;
30853075 else
0 commit comments