9
9
ObjectDefineProperty,
10
10
ObjectEntries,
11
11
ObjectHasOwn,
12
- ObjectKeys,
13
12
Promise,
14
13
Proxy,
15
14
ReflectApply,
@@ -46,10 +45,7 @@ const { Duplex } = require('stream');
46
45
const tls = require ( 'tls' ) ;
47
46
const { setImmediate, setTimeout, clearTimeout } = require ( 'timers' ) ;
48
47
49
- const {
50
- kIncomingMessage,
51
- _checkIsHttpToken : checkIsHttpToken ,
52
- } = require ( '_http_common' ) ;
48
+ const { kIncomingMessage } = require ( '_http_common' ) ;
53
49
const { kServerResponse, Server : HttpServer , httpServerPreClose, setupConnectionsTracking } = require ( '_http_server' ) ;
54
50
const JSStreamSocket = require ( 'internal/js_stream_socket' ) ;
55
51
@@ -68,9 +64,6 @@ const {
68
64
codes : {
69
65
ERR_HTTP2_ALTSVC_INVALID_ORIGIN ,
70
66
ERR_HTTP2_ALTSVC_LENGTH ,
71
- ERR_HTTP2_CONNECT_AUTHORITY ,
72
- ERR_HTTP2_CONNECT_PATH ,
73
- ERR_HTTP2_CONNECT_SCHEME ,
74
67
ERR_HTTP2_GOAWAY_SESSION ,
75
68
ERR_HTTP2_HEADERS_AFTER_RESPOND ,
76
69
ERR_HTTP2_HEADERS_SENT ,
@@ -108,7 +101,6 @@ const {
108
101
ERR_INVALID_ARG_TYPE ,
109
102
ERR_INVALID_ARG_VALUE ,
110
103
ERR_INVALID_CHAR ,
111
- ERR_INVALID_HTTP_TOKEN ,
112
104
ERR_OUT_OF_RANGE ,
113
105
ERR_SOCKET_CLOSED ,
114
106
} ,
@@ -137,23 +129,26 @@ const {
137
129
const {
138
130
assertIsObject,
139
131
assertIsArray,
140
- assertValidPseudoHeader,
141
132
assertValidPseudoHeaderResponse,
142
133
assertValidPseudoHeaderTrailer,
143
134
assertWithinRange,
135
+ buildNgHeaderString,
144
136
getAuthority,
145
137
getDefaultSettings,
146
138
getSessionState,
147
139
getSettings,
148
140
getStreamState,
149
141
isPayloadMeaningless,
142
+ kAuthority,
150
143
kSensitiveHeaders,
151
144
kSocket,
152
145
kRequest,
146
+ kProtocol,
153
147
kProxySocket,
154
- mapToHeaders,
155
148
MAX_ADDITIONAL_SETTINGS ,
156
149
NghttpError,
150
+ prepareRequestHeadersArray,
151
+ prepareRequestHeadersObject,
157
152
remoteCustomSettingsToBuffer,
158
153
sessionName,
159
154
toHeaderObject,
@@ -229,7 +224,6 @@ const NETServer = net.Server;
229
224
const TLSServer = tls . Server ;
230
225
231
226
const kAlpnProtocol = Symbol ( 'alpnProtocol' ) ;
232
- const kAuthority = Symbol ( 'authority' ) ;
233
227
const kEncrypted = Symbol ( 'encrypted' ) ;
234
228
const kID = Symbol ( 'id' ) ;
235
229
const kInit = Symbol ( 'init' ) ;
@@ -241,7 +235,6 @@ const kOwner = owner_symbol;
241
235
const kOrigin = Symbol ( 'origin' ) ;
242
236
const kPendingRequestCalls = Symbol ( 'kPendingRequestCalls' ) ;
243
237
const kProceed = Symbol ( 'proceed' ) ;
244
- const kProtocol = Symbol ( 'protocol' ) ;
245
238
const kRemoteSettings = Symbol ( 'remote-settings' ) ;
246
239
const kRequestAsyncResource = Symbol ( 'requestAsyncResource' ) ;
247
240
const kSelectPadding = Symbol ( 'select-padding' ) ;
@@ -286,7 +279,6 @@ const {
286
279
HTTP2_HEADER_DATE ,
287
280
HTTP2_HEADER_METHOD ,
288
281
HTTP2_HEADER_PATH ,
289
- HTTP2_HEADER_PROTOCOL ,
290
282
HTTP2_HEADER_SCHEME ,
291
283
HTTP2_HEADER_STATUS ,
292
284
HTTP2_HEADER_CONTENT_LENGTH ,
@@ -301,7 +293,6 @@ const {
301
293
302
294
HTTP2_METHOD_GET ,
303
295
HTTP2_METHOD_HEAD ,
304
- HTTP2_METHOD_CONNECT ,
305
296
306
297
HTTP_STATUS_CONTINUE ,
307
298
HTTP_STATUS_RESET_CONTENT ,
@@ -1767,7 +1758,7 @@ class ClientHttp2Session extends Http2Session {
1767
1758
1768
1759
// Submits a new HTTP2 request to the connected peer. Returns the
1769
1760
// associated Http2Stream instance.
1770
- request ( headers , options ) {
1761
+ request ( headersParam , options ) {
1771
1762
debugSessionObj ( this , 'initiating request' ) ;
1772
1763
1773
1764
if ( this . destroyed )
@@ -1778,62 +1769,61 @@ class ClientHttp2Session extends Http2Session {
1778
1769
1779
1770
this [ kUpdateTimer ] ( ) ;
1780
1771
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
+ ) ;
1790
1807
}
1791
1808
1792
- assertIsObject ( headers , 'headers' ) ;
1793
1809
assertIsObject ( options , 'options' ) ;
1794
-
1795
- headers = ObjectAssign ( { __proto__ : null } , headers ) ;
1796
1810
options = { ...options } ;
1797
1811
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
-
1819
1812
setAndValidatePriorityOptions ( options ) ;
1820
1813
1821
1814
if ( options . endStream === undefined ) {
1822
1815
// For some methods, we know that a payload is meaningless, so end the
1823
1816
// stream by default if the user has not specifically indicated a
1824
1817
// preference.
1825
- options . endStream = isPayloadMeaningless ( headers [ HTTP2_HEADER_METHOD ] ) ;
1818
+ options . endStream = isPayloadMeaningless ( method ) ;
1826
1819
} else {
1827
1820
validateBoolean ( options . endStream , 'options.endStream' ) ;
1828
1821
}
1829
1822
1830
- const headersList = mapToHeaders ( headers ) ;
1831
-
1832
1823
// eslint-disable-next-line no-use-before-define
1833
1824
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 } ` ;
1837
1827
const reqAsync = new AsyncResource ( 'PendingRequest' ) ;
1838
1828
stream [ kRequestAsyncResource ] = reqAsync ;
1839
1829
@@ -2295,7 +2285,7 @@ class Http2Stream extends Duplex {
2295
2285
2296
2286
this [ kUpdateTimer ] ( ) ;
2297
2287
2298
- const headersList = mapToHeaders ( headers , assertValidPseudoHeaderTrailer ) ;
2288
+ const headersList = buildNgHeaderString ( headers , assertValidPseudoHeaderTrailer ) ;
2299
2289
this [ kSentTrailers ] = headers ;
2300
2290
2301
2291
// 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,
2528
2518
2529
2519
let headersList ;
2530
2520
try {
2531
- headersList = mapToHeaders ( headers , assertValidPseudoHeaderResponse ) ;
2521
+ headersList = buildNgHeaderString ( headers , assertValidPseudoHeaderResponse ) ;
2532
2522
} catch ( err ) {
2533
2523
self . destroy ( err ) ;
2534
2524
return ;
@@ -2752,7 +2742,7 @@ class ServerHttp2Stream extends Http2Stream {
2752
2742
if ( headers [ HTTP2_HEADER_METHOD ] === HTTP2_METHOD_HEAD )
2753
2743
headRequest = options . endStream = true ;
2754
2744
2755
- const headersList = mapToHeaders ( headers ) ;
2745
+ const headersList = buildNgHeaderString ( headers ) ;
2756
2746
2757
2747
const streamOptions = options . endStream ? STREAM_OPTION_EMPTY_PAYLOAD : 0 ;
2758
2748
@@ -2816,7 +2806,7 @@ class ServerHttp2Stream extends Http2Stream {
2816
2806
}
2817
2807
2818
2808
headers = processHeaders ( headers , options ) ;
2819
- const headersList = mapToHeaders ( headers , assertValidPseudoHeaderResponse ) ;
2809
+ const headersList = buildNgHeaderString ( headers , assertValidPseudoHeaderResponse ) ;
2820
2810
this [ kSentHeaders ] = headers ;
2821
2811
2822
2812
state . flags |= STREAM_FLAGS_HEADERS_SENT ;
@@ -2984,7 +2974,7 @@ class ServerHttp2Stream extends Http2Stream {
2984
2974
2985
2975
this [ kUpdateTimer ] ( ) ;
2986
2976
2987
- const headersList = mapToHeaders ( headers , assertValidPseudoHeaderResponse ) ;
2977
+ const headersList = buildNgHeaderString ( headers , assertValidPseudoHeaderResponse ) ;
2988
2978
if ( ! this [ kInfoHeaders ] )
2989
2979
this [ kInfoHeaders ] = [ headers ] ;
2990
2980
else
0 commit comments