Skip to content

Commit 0a84e95

Browse files
committed
http: improve errors thrown in header validation
PR-URL: #16719 Fixes: #16714 Reviewed-By: Anatoli Papirovski <apapirovski@mac.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 11a9f36 commit 0a84e95

File tree

6 files changed

+30
-26
lines changed

6 files changed

+30
-26
lines changed

doc/api/errors.md

+5
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,11 @@ more headers.
754754
Used when an invalid character is found in an HTTP response status message
755755
(reason phrase).
756756

757+
<a id="ERR_HTTP_INVALID_HEADER_VALUE"></a>
758+
### ERR_HTTP_INVALID_HEADER_VALUE
759+
760+
Used to indicate that an invalid HTTP header value has been specified.
761+
757762
<a id="ERR_HTTP_INVALID_STATUS_CODE"></a>
758763
### ERR_HTTP_INVALID_STATUS_CODE
759764

lib/_http_outgoing.js

+18-20
Original file line numberDiff line numberDiff line change
@@ -437,16 +437,7 @@ function _storeHeader(firstLine, headers) {
437437

438438
function storeHeader(self, state, key, value, validate) {
439439
if (validate) {
440-
if (typeof key !== 'string' || !key || !checkIsHttpToken(key)) {
441-
throw new errors.TypeError(
442-
'ERR_INVALID_HTTP_TOKEN', 'Header name', key);
443-
}
444-
if (value === undefined) {
445-
throw new errors.TypeError('ERR_MISSING_ARGS', `header "${key}"`);
446-
} else if (checkInvalidHeaderChar(value)) {
447-
debug('Header "%s" contains invalid characters', key);
448-
throw new errors.TypeError('ERR_INVALID_CHAR', 'header content', key);
449-
}
440+
validateHeader(key, value);
450441
}
451442
state.header += key + ': ' + escapeHeaderValue(value) + CRLF;
452443
matchHeader(self, state, key, value);
@@ -494,20 +485,27 @@ function matchHeader(self, state, field, value) {
494485
}
495486
}
496487

497-
function validateHeader(msg, name, value) {
498-
if (typeof name !== 'string' || !name || !checkIsHttpToken(name))
499-
throw new errors.TypeError('ERR_INVALID_HTTP_TOKEN', 'Header name', name);
500-
if (value === undefined)
501-
throw new errors.TypeError('ERR_MISSING_ARGS', 'value');
502-
if (msg._header)
503-
throw new errors.Error('ERR_HTTP_HEADERS_SENT', 'set');
504-
if (checkInvalidHeaderChar(value)) {
488+
function validateHeader(name, value) {
489+
let err;
490+
if (typeof name !== 'string' || !name || !checkIsHttpToken(name)) {
491+
err = new errors.TypeError('ERR_INVALID_HTTP_TOKEN', 'Header name', name);
492+
} else if (value === undefined) {
493+
err = new errors.TypeError('ERR_HTTP_INVALID_HEADER_VALUE', value, name);
494+
} else if (checkInvalidHeaderChar(value)) {
505495
debug('Header "%s" contains invalid characters', name);
506-
throw new errors.TypeError('ERR_INVALID_CHAR', 'header content', name);
496+
err = new errors.TypeError('ERR_INVALID_CHAR', 'header content', name);
497+
}
498+
if (err !== undefined) {
499+
Error.captureStackTrace(err, validateHeader);
500+
throw err;
507501
}
508502
}
503+
509504
OutgoingMessage.prototype.setHeader = function setHeader(name, value) {
510-
validateHeader(this, name, value);
505+
if (this._header) {
506+
throw new errors.Error('ERR_HTTP_HEADERS_SENT', 'set');
507+
}
508+
validateHeader(name, value);
511509

512510
if (!this[outHeadersKey])
513511
this[outHeadersKey] = {};

lib/internal/errors.js

+1
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,7 @@ E('ERR_HTTP2_UNSUPPORTED_PROTOCOL',
317317
E('ERR_HTTP_HEADERS_SENT',
318318
'Cannot %s headers after they are sent to the client');
319319
E('ERR_HTTP_INVALID_CHAR', 'Invalid character in statusMessage.');
320+
E('ERR_HTTP_INVALID_HEADER_VALUE', 'Invalid value "%s" for header "%s"');
320321
E('ERR_HTTP_INVALID_STATUS_CODE',
321322
(originalStatusCode) => `Invalid status code: ${originalStatusCode}`);
322323
E('ERR_HTTP_TRAILER_INVALID',

test/parallel/test-http-mutable-headers.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,9 @@ const s = http.createServer(common.mustCall((req, res) => {
6161
common.expectsError(
6262
() => res.setHeader('someHeader'),
6363
{
64-
code: 'ERR_MISSING_ARGS',
64+
code: 'ERR_HTTP_INVALID_HEADER_VALUE',
6565
type: TypeError,
66-
message: 'The "value" argument must be specified'
66+
message: 'Invalid value "undefined" for header "someHeader"'
6767
}
6868
);
6969
common.expectsError(

test/parallel/test-http-outgoing-proto.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ assert.throws(() => {
3434
const outgoingMessage = new OutgoingMessage();
3535
outgoingMessage.setHeader('test');
3636
}, common.expectsError({
37-
code: 'ERR_MISSING_ARGS',
37+
code: 'ERR_HTTP_INVALID_HEADER_VALUE',
3838
type: TypeError,
39-
message: 'The "value" argument must be specified'
39+
message: 'Invalid value "undefined" for header "test"'
4040
}));
4141

4242
assert.throws(() => {

test/parallel/test-http-write-head.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@ const s = http.createServer(common.mustCall((req, res) => {
4444
common.expectsError(
4545
() => res.setHeader('foo', undefined),
4646
{
47-
code: 'ERR_MISSING_ARGS',
47+
code: 'ERR_HTTP_INVALID_HEADER_VALUE',
4848
type: TypeError,
49-
message: 'The "value" argument must be specified'
49+
message: 'Invalid value "undefined" for header "foo"'
5050
}
5151
);
5252

0 commit comments

Comments
 (0)