Skip to content

Commit 0fb005a

Browse files
RaisinTentargos
authored andcommitted
http2: set Http2Stream#sentHeaders for raw headers
When #57917 added support for sending raw header arrays, Http2Stream#sentHeaders was set only for header objects. This change also sets it for raw headers by lazily instantiating the property to avoid any performance impact on the fast path. Signed-off-by: Darshan Sen <raisinten@gmail.com> PR-URL: #59244 Reviewed-By: Tim Perry <pimterry@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
1 parent 7b94982 commit 0fb005a

4 files changed

Lines changed: 61 additions & 2 deletions

File tree

‎lib/internal/http2/core.js‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ const kProceed = Symbol('proceed');
254254
constkRemoteSettings=Symbol('remote-settings');
255255
constkRequestAsyncResource=Symbol('requestAsyncResource');
256256
constkSentHeaders=Symbol('sent-headers');
257+
constkRawHeaders=Symbol('raw-headers');
257258
constkSentTrailers=Symbol('sent-trailers');
258259
constkServer=Symbol('server');
259260
constkState=Symbol('state');
@@ -1807,12 +1808,14 @@ class ClientHttp2Session extends Http2Session {
18071808

18081809
letheadersList;
18091810
letheadersObject;
1811+
letrawHeaders;
18101812
letscheme;
18111813
letauthority;
18121814
letmethod;
18131815

18141816
if(ArrayIsArray(headersParam)){
18151817
({
1818+
rawHeaders,
18161819
headersList,
18171820
scheme,
18181821
authority,
@@ -1859,6 +1862,7 @@ class ClientHttp2Session extends Http2Session {
18591862
// eslint-disable-next-line no-use-before-define
18601863
conststream=newClientHttp2Stream(this,undefined,undefined,{});
18611864
stream[kSentHeaders]=headersObject;// N.b. Only set for object headers, not raw headers
1865+
stream[kRawHeaders]=rawHeaders;// N.b. Only set for raw headers, not object headers
18621866
stream[kOrigin]=`${scheme}://${authority}`;
18631867
constreqAsync=newAsyncResource('PendingRequest');
18641868
stream[kRequestAsyncResource]=reqAsync;
@@ -2128,6 +2132,33 @@ class Http2Stream extends Duplex {
21282132
}
21292133

21302134
getsentHeaders(){
2135+
if(this[kSentHeaders]||!this[kRawHeaders]){
2136+
returnthis[kSentHeaders];
2137+
}
2138+
2139+
constrawHeaders=this[kRawHeaders];
2140+
constheadersObject={__proto__: null};
2141+
2142+
for(leti=0;i<rawHeaders.length;i+=2){
2143+
constkey=rawHeaders[i];
2144+
constvalue=rawHeaders[i+1];
2145+
2146+
constexisting=headersObject[key];
2147+
if(existing===undefined){
2148+
headersObject[key]=value;
2149+
}elseif(ArrayIsArray(existing)){
2150+
existing.push(value);
2151+
}else{
2152+
headersObject[key]=[existing,value];
2153+
}
2154+
}
2155+
2156+
if(rawHeaders[kSensitiveHeaders]!==undefined){
2157+
headersObject[kSensitiveHeaders]=rawHeaders[kSensitiveHeaders];
2158+
}
2159+
2160+
this[kSentHeaders]=headersObject;
2161+
21312162
returnthis[kSentHeaders];
21322163
}
21332164

‎lib/internal/http2/util.js‎

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -678,15 +678,23 @@ function prepareRequestHeadersArray(headers, session) {
678678
thrownewERR_HTTP2_CONNECT_PATH();
679679
}
680680

681-
constheadersList=buildNgHeaderString(
681+
constrawHeaders=
682682
additionalPsuedoHeaders.length ?
683683
additionalPsuedoHeaders.concat(headers) :
684-
headers,
684+
headers;
685+
686+
if(headers[kSensitiveHeaders]!==undefined){
687+
rawHeaders[kSensitiveHeaders]=headers[kSensitiveHeaders];
688+
}
689+
690+
constheadersList=buildNgHeaderString(
691+
rawHeaders,
685692
assertValidPseudoHeader,
686693
headers[kSensitiveHeaders],
687694
);
688695

689696
return{
697+
rawHeaders,
690698
headersList,
691699
scheme,
692700
authority: authority??headers[HTTP2_HEADER_HOST],

‎test/parallel/test-http2-raw-headers.js‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,16 @@ const http2 = require('http2');
3939
'a','c',
4040
]).end();
4141

42+
assert.deepStrictEqual(req.sentHeaders,{
43+
'__proto__': null,
44+
':path': '/foobar',
45+
':scheme': 'http',
46+
':authority': `localhost:${server.address().port}`,
47+
':method': 'GET',
48+
'a': ['b','c'],
49+
'x-FOO': 'bar',
50+
});
51+
4252
req.on('response',common.mustCall((headers)=>{
4353
assert.strictEqual(headers[':status'],200);
4454
client.close();

‎test/parallel/test-http2-sensitive-headers.js‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,16 @@ const { duplexPair } = require('stream');
7272

7373
constreq=client.request(rawHeaders);
7474

75+
assert.deepStrictEqual(req.sentHeaders,{
76+
'__proto__': null,
77+
':method': 'GET',
78+
':authority': 'localhost:80',
79+
':scheme': 'http',
80+
':path': '/',
81+
'secret': 'secret-value',
82+
[http2.sensitiveHeaders]: ['secret'],
83+
});
84+
7585
req.on('response',common.mustCall((headers)=>{
7686
assert.strictEqual(headers[':status'],200);
7787
}));

0 commit comments

Comments
 (0)