Skip to content

Commit cd7df56

Browse files
jasnellrvagg
authored andcommitted
http2: throw from mapToHeaders
PR-URL: #24063 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Note: Landed with one collaborator approval after PR was open for 18 days
1 parent 1a74fad commit cd7df56

File tree

4 files changed

+42
-56
lines changed

4 files changed

+42
-56
lines changed

lib/internal/http2/core.js

+6-14
Original file line numberDiff line numberDiff line change
@@ -1484,8 +1484,6 @@ class ClientHttp2Session extends Http2Session {
14841484
}
14851485

14861486
const headersList = mapToHeaders(headers);
1487-
if (!Array.isArray(headersList))
1488-
throw headersList;
14891487

14901488
const stream = new ClientHttp2Stream(this, undefined, undefined, {});
14911489
stream[kSentHeaders] = headers;
@@ -1890,8 +1888,6 @@ class Http2Stream extends Duplex {
18901888
this[kUpdateTimer]();
18911889

18921890
const headersList = mapToHeaders(headers, assertValidPseudoHeaderTrailer);
1893-
if (!Array.isArray(headersList))
1894-
throw headersList;
18951891
this[kSentTrailers] = headers;
18961892

18971893
// Send the trailers in setImmediate so we don't do it on nghttp2 stack.
@@ -2058,12 +2054,14 @@ function processRespondWithFD(self, fd, headers, offset = 0, length = -1,
20582054
const state = self[kState];
20592055
state.flags |= STREAM_FLAGS_HEADERS_SENT;
20602056

2061-
const headersList = mapToHeaders(headers, assertValidPseudoHeaderResponse);
2062-
self[kSentHeaders] = headers;
2063-
if (!Array.isArray(headersList)) {
2064-
self.destroy(headersList);
2057+
let headersList;
2058+
try {
2059+
headersList = mapToHeaders(headers, assertValidPseudoHeaderResponse);
2060+
} catch (err) {
2061+
self.destroy(err);
20652062
return;
20662063
}
2064+
self[kSentHeaders] = headers;
20672065

20682066
// Close the writable side of the stream, but only as far as the writable
20692067
// stream implementation is concerned.
@@ -2287,8 +2285,6 @@ class ServerHttp2Stream extends Http2Stream {
22872285
options.readable = false;
22882286

22892287
const headersList = mapToHeaders(headers);
2290-
if (!Array.isArray(headersList))
2291-
throw headersList;
22922288

22932289
const streamOptions = options.endStream ? STREAM_OPTION_EMPTY_PAYLOAD : 0;
22942290

@@ -2365,8 +2361,6 @@ class ServerHttp2Stream extends Http2Stream {
23652361
}
23662362

23672363
const headersList = mapToHeaders(headers, assertValidPseudoHeaderResponse);
2368-
if (!Array.isArray(headersList))
2369-
throw headersList;
23702364
this[kSentHeaders] = headers;
23712365

23722366
state.flags |= STREAM_FLAGS_HEADERS_SENT;
@@ -2527,8 +2521,6 @@ class ServerHttp2Stream extends Http2Stream {
25272521
this[kUpdateTimer]();
25282522

25292523
const headersList = mapToHeaders(headers, assertValidPseudoHeaderResponse);
2530-
if (!Array.isArray(headersList))
2531-
throw headersList;
25322524
if (!this[kInfoHeaders])
25332525
this[kInfoHeaders] = [headers];
25342526
else

lib/internal/http2/util.js

+7-7
Original file line numberDiff line numberDiff line change
@@ -406,22 +406,22 @@ function assertValidPseudoHeader(key) {
406406
if (!kValidPseudoHeaders.has(key)) {
407407
const err = new ERR_HTTP2_INVALID_PSEUDOHEADER(key);
408408
Error.captureStackTrace(err, assertValidPseudoHeader);
409-
return err;
409+
throw err;
410410
}
411411
}
412412

413413
function assertValidPseudoHeaderResponse(key) {
414414
if (key !== ':status') {
415415
const err = new ERR_HTTP2_INVALID_PSEUDOHEADER(key);
416416
Error.captureStackTrace(err, assertValidPseudoHeaderResponse);
417-
return err;
417+
throw err;
418418
}
419419
}
420420

421421
function assertValidPseudoHeaderTrailer(key) {
422422
const err = new ERR_HTTP2_INVALID_PSEUDOHEADER(key);
423423
Error.captureStackTrace(err, assertValidPseudoHeaderTrailer);
424-
return err;
424+
throw err;
425425
}
426426

427427
function mapToHeaders(map,
@@ -454,26 +454,26 @@ function mapToHeaders(map,
454454
break;
455455
default:
456456
if (isSingleValueHeader)
457-
return new ERR_HTTP2_HEADER_SINGLE_VALUE(key);
457+
throw new ERR_HTTP2_HEADER_SINGLE_VALUE(key);
458458
}
459459
} else {
460460
value = String(value);
461461
}
462462
if (isSingleValueHeader) {
463463
if (singles.has(key))
464-
return new ERR_HTTP2_HEADER_SINGLE_VALUE(key);
464+
throw new ERR_HTTP2_HEADER_SINGLE_VALUE(key);
465465
singles.add(key);
466466
}
467467
if (key[0] === ':') {
468468
err = assertValuePseudoHeader(key);
469469
if (err !== undefined)
470-
return err;
470+
throw err;
471471
ret = `${key}\0${value}\0${ret}`;
472472
count++;
473473
continue;
474474
}
475475
if (isIllegalConnectionSpecificHeader(key, value)) {
476-
return new ERR_HTTP2_INVALID_CONNECTION_HEADERS(key);
476+
throw new ERR_HTTP2_INVALID_CONNECTION_HEADERS(key);
477477
}
478478
if (isArray) {
479479
for (var k = 0; k < value.length; k++) {

test/parallel/test-http2-util-assert-valid-pseudoheader.js

+11-19
Original file line numberDiff line numberDiff line change
@@ -8,24 +8,16 @@ const common = require('../common');
88
// have to test it through mapToHeaders
99

1010
const { mapToHeaders } = require('internal/http2/util');
11-
const assert = require('assert');
1211

13-
function isNotError(val) {
14-
assert(!(val instanceof Error));
15-
}
12+
// These should not throw
13+
mapToHeaders({ ':status': 'a' });
14+
mapToHeaders({ ':path': 'a' });
15+
mapToHeaders({ ':authority': 'a' });
16+
mapToHeaders({ ':scheme': 'a' });
17+
mapToHeaders({ ':method': 'a' });
1618

17-
function isError(val) {
18-
common.expectsError({
19-
code: 'ERR_HTTP2_INVALID_PSEUDOHEADER',
20-
type: TypeError,
21-
message: '":foo" is an invalid pseudoheader or is used incorrectly'
22-
})(val);
23-
}
24-
25-
isNotError(mapToHeaders({ ':status': 'a' }));
26-
isNotError(mapToHeaders({ ':path': 'a' }));
27-
isNotError(mapToHeaders({ ':authority': 'a' }));
28-
isNotError(mapToHeaders({ ':scheme': 'a' }));
29-
isNotError(mapToHeaders({ ':method': 'a' }));
30-
31-
isError(mapToHeaders({ ':foo': 'a' }));
19+
common.expectsError(() => mapToHeaders({ ':foo': 'a' }), {
20+
code: 'ERR_HTTP2_INVALID_PSEUDOHEADER',
21+
type: TypeError,
22+
message: '":foo" is an invalid pseudoheader or is used incorrectly'
23+
});

test/parallel/test-http2-util-headers-list.js

+18-16
Original file line numberDiff line numberDiff line change
@@ -175,11 +175,11 @@ const {
175175
':statuS': 204,
176176
};
177177

178-
common.expectsError({
178+
common.expectsError(() => mapToHeaders(headers), {
179179
code: 'ERR_HTTP2_HEADER_SINGLE_VALUE',
180180
type: TypeError,
181181
message: 'Header field ":status" must only have a single value'
182-
})(mapToHeaders(headers));
182+
});
183183
}
184184

185185
// The following are not allowed to have multiple values
@@ -224,10 +224,10 @@ const {
224224
HTTP2_HEADER_X_CONTENT_TYPE_OPTIONS
225225
].forEach((name) => {
226226
const msg = `Header field "${name}" must only have a single value`;
227-
common.expectsError({
227+
common.expectsError(() => mapToHeaders({ [name]: [1, 2, 3] }), {
228228
code: 'ERR_HTTP2_HEADER_SINGLE_VALUE',
229229
message: msg
230-
})(mapToHeaders({ [name]: [1, 2, 3] }));
230+
});
231231
});
232232

233233
[
@@ -281,30 +281,32 @@ const {
281281
'Proxy-Connection',
282282
'Keep-Alive'
283283
].forEach((name) => {
284-
common.expectsError({
284+
common.expectsError(() => mapToHeaders({ [name]: 'abc' }), {
285285
code: 'ERR_HTTP2_INVALID_CONNECTION_HEADERS',
286286
name: 'TypeError [ERR_HTTP2_INVALID_CONNECTION_HEADERS]',
287287
message: 'HTTP/1 Connection specific headers are forbidden: ' +
288288
`"${name.toLowerCase()}"`
289-
})(mapToHeaders({ [name]: 'abc' }));
289+
});
290290
});
291291

292-
common.expectsError({
292+
common.expectsError(() => mapToHeaders({ [HTTP2_HEADER_TE]: ['abc'] }), {
293293
code: 'ERR_HTTP2_INVALID_CONNECTION_HEADERS',
294294
name: 'TypeError [ERR_HTTP2_INVALID_CONNECTION_HEADERS]',
295295
message: 'HTTP/1 Connection specific headers are forbidden: ' +
296296
`"${HTTP2_HEADER_TE}"`
297-
})(mapToHeaders({ [HTTP2_HEADER_TE]: ['abc'] }));
297+
});
298298

299-
common.expectsError({
300-
code: 'ERR_HTTP2_INVALID_CONNECTION_HEADERS',
301-
name: 'TypeError [ERR_HTTP2_INVALID_CONNECTION_HEADERS]',
302-
message: 'HTTP/1 Connection specific headers are forbidden: ' +
303-
`"${HTTP2_HEADER_TE}"`
304-
})(mapToHeaders({ [HTTP2_HEADER_TE]: ['abc', 'trailers'] }));
299+
common.expectsError(
300+
() => mapToHeaders({ [HTTP2_HEADER_TE]: ['abc', 'trailers'] }), {
301+
code: 'ERR_HTTP2_INVALID_CONNECTION_HEADERS',
302+
name: 'TypeError [ERR_HTTP2_INVALID_CONNECTION_HEADERS]',
303+
message: 'HTTP/1 Connection specific headers are forbidden: ' +
304+
`"${HTTP2_HEADER_TE}"`
305+
});
305306

306-
assert(!(mapToHeaders({ te: 'trailers' }) instanceof Error));
307-
assert(!(mapToHeaders({ te: ['trailers'] }) instanceof Error));
307+
// These should not throw
308+
mapToHeaders({ te: 'trailers' });
309+
mapToHeaders({ te: ['trailers'] });
308310

309311

310312
{

0 commit comments

Comments
 (0)