99 ObjectDefineProperty,
1010 ObjectEntries,
1111 ObjectHasOwn,
12- ObjectKeys,
1312 Promise,
1413 Proxy,
1514 ReflectApply,
@@ -46,10 +45,7 @@ const { Duplex } = require('stream');
4645const tls = require ( 'tls' ) ;
4746const { setImmediate, setTimeout, clearTimeout } = require ( 'timers' ) ;
4847
49- const {
50- kIncomingMessage,
51- _checkIsHttpToken : checkIsHttpToken ,
52- } = require ( '_http_common' ) ;
48+ const { kIncomingMessage } = require ( '_http_common' ) ;
5349const { kServerResponse, Server : HttpServer , httpServerPreClose, setupConnectionsTracking } = require ( '_http_server' ) ;
5450const JSStreamSocket = require ( 'internal/js_stream_socket' ) ;
5551
@@ -68,9 +64,6 @@ const {
6864 codes : {
6965 ERR_HTTP2_ALTSVC_INVALID_ORIGIN ,
7066 ERR_HTTP2_ALTSVC_LENGTH ,
71- ERR_HTTP2_CONNECT_AUTHORITY ,
72- ERR_HTTP2_CONNECT_PATH ,
73- ERR_HTTP2_CONNECT_SCHEME ,
7467 ERR_HTTP2_GOAWAY_SESSION ,
7568 ERR_HTTP2_HEADERS_AFTER_RESPOND ,
7669 ERR_HTTP2_HEADERS_SENT ,
@@ -108,7 +101,6 @@ const {
108101 ERR_INVALID_ARG_TYPE ,
109102 ERR_INVALID_ARG_VALUE ,
110103 ERR_INVALID_CHAR ,
111- ERR_INVALID_HTTP_TOKEN ,
112104 ERR_OUT_OF_RANGE ,
113105 ERR_SOCKET_CLOSED ,
114106 } ,
@@ -137,23 +129,26 @@ const {
137129const {
138130 assertIsObject,
139131 assertIsArray,
140- assertValidPseudoHeader,
141132 assertValidPseudoHeaderResponse,
142133 assertValidPseudoHeaderTrailer,
143134 assertWithinRange,
135+ buildNgHeaderString,
144136 getAuthority,
145137 getDefaultSettings,
146138 getSessionState,
147139 getSettings,
148140 getStreamState,
149141 isPayloadMeaningless,
142+ kAuthority,
150143 kSensitiveHeaders,
151144 kSocket,
152145 kRequest,
146+ kProtocol,
153147 kProxySocket,
154- mapToHeaders,
155148 MAX_ADDITIONAL_SETTINGS ,
156149 NghttpError,
150+ prepareRequestHeadersArray,
151+ prepareRequestHeadersObject,
157152 remoteCustomSettingsToBuffer,
158153 sessionName,
159154 toHeaderObject,
@@ -229,7 +224,6 @@ const NETServer = net.Server;
229224const TLSServer = tls . Server ;
230225
231226const kAlpnProtocol = Symbol ( 'alpnProtocol' ) ;
232- const kAuthority = Symbol ( 'authority' ) ;
233227const kEncrypted = Symbol ( 'encrypted' ) ;
234228const kID = Symbol ( 'id' ) ;
235229const kInit = Symbol ( 'init' ) ;
@@ -241,7 +235,6 @@ const kOwner = owner_symbol;
241235const kOrigin = Symbol ( 'origin' ) ;
242236const kPendingRequestCalls = Symbol ( 'kPendingRequestCalls' ) ;
243237const kProceed = Symbol ( 'proceed' ) ;
244- const kProtocol = Symbol ( 'protocol' ) ;
245238const kRemoteSettings = Symbol ( 'remote-settings' ) ;
246239const kRequestAsyncResource = Symbol ( 'requestAsyncResource' ) ;
247240const kSelectPadding = Symbol ( 'select-padding' ) ;
@@ -286,7 +279,6 @@ const {
286279 HTTP2_HEADER_DATE ,
287280 HTTP2_HEADER_METHOD ,
288281 HTTP2_HEADER_PATH ,
289- HTTP2_HEADER_PROTOCOL ,
290282 HTTP2_HEADER_SCHEME ,
291283 HTTP2_HEADER_STATUS ,
292284 HTTP2_HEADER_CONTENT_LENGTH ,
@@ -301,7 +293,6 @@ const {
301293
302294 HTTP2_METHOD_GET ,
303295 HTTP2_METHOD_HEAD ,
304- HTTP2_METHOD_CONNECT ,
305296
306297 HTTP_STATUS_CONTINUE ,
307298 HTTP_STATUS_RESET_CONTENT ,
@@ -1767,7 +1758,7 @@ class ClientHttp2Session extends Http2Session {
17671758
17681759 // Submits a new HTTP2 request to the connected peer. Returns the
17691760 // associated Http2Stream instance.
1770- request ( headers , options ) {
1761+ request ( headersParam , options ) {
17711762 debugSessionObj ( this , 'initiating request' ) ;
17721763
17731764 if ( this . destroyed )
@@ -1778,62 +1769,61 @@ class ClientHttp2Session extends Http2Session {
17781769
17791770 this [ kUpdateTimer ] ( ) ;
17801771
1781- if ( headers !== null && headers !== undefined ) {
1782- const keys = ObjectKeys ( headers ) ;
1783- for ( let i = 0 ; i < keys . length ; i ++ ) {
1784- const header = keys [ i ] ;
1785- if ( header [ 0 ] === ':' ) {
1786- assertValidPseudoHeader ( header ) ;
1787- } else if ( header && ! checkIsHttpToken ( header ) )
1788- this . destroy ( new ERR_INVALID_HTTP_TOKEN ( 'Header name' , header ) ) ;
1789- }
1772+ let headersList ;
1773+ let headersObject ;
1774+ let scheme ;
1775+ let authority ;
1776+ let method ;
1777+
1778+ if ( ArrayIsArray ( headersParam ) ) {
1779+ ( {
1780+ headersList,
1781+ scheme,
1782+ authority,
1783+ method,
1784+ } = prepareRequestHeadersArray ( headersParam , this ) ) ;
1785+ } else if ( ! ! headersParam && typeof headersParam === 'object' ) {
1786+ ( {
1787+ headersObject,
1788+ headersList,
1789+ scheme,
1790+ authority,
1791+ method,
1792+ } = prepareRequestHeadersObject ( headersParam , this ) ) ;
1793+ } else if ( headersParam === undefined ) {
1794+ ( {
1795+ headersObject,
1796+ headersList,
1797+ scheme,
1798+ authority,
1799+ method,
1800+ } = prepareRequestHeadersObject ( { } , this ) ) ;
1801+ } else {
1802+ throw new ERR_INVALID_ARG_TYPE . HideStackFramesError (
1803+ 'headers' ,
1804+ [ 'Object' , 'Array' ] ,
1805+ headersParam ,
1806+ ) ;
17901807 }
17911808
1792- assertIsObject ( headers , 'headers' ) ;
17931809 assertIsObject ( options , 'options' ) ;
1794-
1795- headers = ObjectAssign ( { __proto__ : null } , headers ) ;
17961810 options = { ...options } ;
17971811
1798- if ( headers [ HTTP2_HEADER_METHOD ] === undefined )
1799- headers [ HTTP2_HEADER_METHOD ] = HTTP2_METHOD_GET ;
1800-
1801- const connect = headers [ HTTP2_HEADER_METHOD ] === HTTP2_METHOD_CONNECT ;
1802-
1803- if ( ! connect || headers [ HTTP2_HEADER_PROTOCOL ] !== undefined ) {
1804- if ( getAuthority ( headers ) === undefined )
1805- headers [ HTTP2_HEADER_AUTHORITY ] = this [ kAuthority ] ;
1806- if ( headers [ HTTP2_HEADER_SCHEME ] === undefined )
1807- headers [ HTTP2_HEADER_SCHEME ] = this [ kProtocol ] . slice ( 0 , - 1 ) ;
1808- if ( headers [ HTTP2_HEADER_PATH ] === undefined )
1809- headers [ HTTP2_HEADER_PATH ] = '/' ;
1810- } else {
1811- if ( headers [ HTTP2_HEADER_AUTHORITY ] === undefined )
1812- throw new ERR_HTTP2_CONNECT_AUTHORITY ( ) ;
1813- if ( headers [ HTTP2_HEADER_SCHEME ] !== undefined )
1814- throw new ERR_HTTP2_CONNECT_SCHEME ( ) ;
1815- if ( headers [ HTTP2_HEADER_PATH ] !== undefined )
1816- throw new ERR_HTTP2_CONNECT_PATH ( ) ;
1817- }
1818-
18191812 setAndValidatePriorityOptions ( options ) ;
18201813
18211814 if ( options . endStream === undefined ) {
18221815 // For some methods, we know that a payload is meaningless, so end the
18231816 // stream by default if the user has not specifically indicated a
18241817 // preference.
1825- options . endStream = isPayloadMeaningless ( headers [ HTTP2_HEADER_METHOD ] ) ;
1818+ options . endStream = isPayloadMeaningless ( method ) ;
18261819 } else {
18271820 validateBoolean ( options . endStream , 'options.endStream' ) ;
18281821 }
18291822
1830- const headersList = mapToHeaders ( headers ) ;
1831-
18321823 // eslint-disable-next-line no-use-before-define
18331824 const stream = new ClientHttp2Stream ( this , undefined , undefined , { } ) ;
1834- stream [ kSentHeaders ] = headers ;
1835- stream [ kOrigin ] = `${ headers [ HTTP2_HEADER_SCHEME ] } ://` +
1836- `${ getAuthority ( headers ) } ` ;
1825+ stream [ kSentHeaders ] = headersObject ; // N.b. Only set for object headers, not raw headers
1826+ stream [ kOrigin ] = `${ scheme } ://${ authority } ` ;
18371827 const reqAsync = new AsyncResource ( 'PendingRequest' ) ;
18381828 stream [ kRequestAsyncResource ] = reqAsync ;
18391829
@@ -2295,7 +2285,7 @@ class Http2Stream extends Duplex {
22952285
22962286 this [ kUpdateTimer ] ( ) ;
22972287
2298- const headersList = mapToHeaders ( headers , assertValidPseudoHeaderTrailer ) ;
2288+ const headersList = buildNgHeaderString ( headers , assertValidPseudoHeaderTrailer ) ;
22992289 this [ kSentTrailers ] = headers ;
23002290
23012291 // Send the trailers in setImmediate so we don't do it on nghttp2 stack.
@@ -2528,7 +2518,7 @@ function processRespondWithFD(self, fd, headers, offset = 0, length = -1,
25282518
25292519 let headersList ;
25302520 try {
2531- headersList = mapToHeaders ( headers , assertValidPseudoHeaderResponse ) ;
2521+ headersList = buildNgHeaderString ( headers , assertValidPseudoHeaderResponse ) ;
25322522 } catch ( err ) {
25332523 self . destroy ( err ) ;
25342524 return ;
@@ -2752,7 +2742,7 @@ class ServerHttp2Stream extends Http2Stream {
27522742 if ( headers [ HTTP2_HEADER_METHOD ] === HTTP2_METHOD_HEAD )
27532743 headRequest = options . endStream = true ;
27542744
2755- const headersList = mapToHeaders ( headers ) ;
2745+ const headersList = buildNgHeaderString ( headers ) ;
27562746
27572747 const streamOptions = options . endStream ? STREAM_OPTION_EMPTY_PAYLOAD : 0 ;
27582748
@@ -2816,7 +2806,7 @@ class ServerHttp2Stream extends Http2Stream {
28162806 }
28172807
28182808 headers = processHeaders ( headers , options ) ;
2819- const headersList = mapToHeaders ( headers , assertValidPseudoHeaderResponse ) ;
2809+ const headersList = buildNgHeaderString ( headers , assertValidPseudoHeaderResponse ) ;
28202810 this [ kSentHeaders ] = headers ;
28212811
28222812 state . flags |= STREAM_FLAGS_HEADERS_SENT ;
@@ -2984,7 +2974,7 @@ class ServerHttp2Stream extends Http2Stream {
29842974
29852975 this [ kUpdateTimer ] ( ) ;
29862976
2987- const headersList = mapToHeaders ( headers , assertValidPseudoHeaderResponse ) ;
2977+ const headersList = buildNgHeaderString ( headers , assertValidPseudoHeaderResponse ) ;
29882978 if ( ! this [ kInfoHeaders ] )
29892979 this [ kInfoHeaders ] = [ headers ] ;
29902980 else
0 commit comments