Skip to content

Commit

Permalink
http: edit _storeHeader to check for Trailer header
Browse files Browse the repository at this point in the history
Test non-chunked message does not have trailer header set,
message will be terminated by the first empty line after the
header fields, regardless of the header fields present in the
message, and thus cannot contain a message body or 'trailers'.

PR-URL: #12990
Ref: #2842
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Yuta Hiroto <hello@about-hiroppy.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Brian White <mscdex@mscdex.net>
  • Loading branch information
arturgvieira authored and jasnell committed Jun 13, 2017
1 parent 0ab4614 commit 80c9ef0
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 0 deletions.
9 changes: 9 additions & 0 deletions lib/_http_outgoing.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const checkInvalidHeaderChar = common._checkInvalidHeaderChar;
const outHeadersKey = require('internal/http').outHeadersKey;
const async_id_symbol = process.binding('async_wrap').async_id_symbol;
const nextTick = require('internal/process/next_tick').nextTick;
const errors = require('internal/errors');

const CRLF = common.CRLF;
const debug = common.debug;
Expand Down Expand Up @@ -427,6 +428,14 @@ function _storeHeader(firstLine, headers) {
}
}

// Test non-chunked message does not have trailer header set,
// message will be terminated by the first empty line after the
// header fields, regardless of the header fields present in the
// message, and thus cannot contain a message body or 'trailers'.
if (this.chunkedEncoding !== true && state.trailer) {
throw new errors.Error('ERR_HTTP_TRAILER_INVALID');
}

this._header = state.header + CRLF;
this._headerSent = false;

Expand Down
2 changes: 2 additions & 0 deletions lib/internal/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ E('ERR_PARSE_HISTORY_DATA',
(oldHistoryPath) => `Could not parse history data in ${oldHistoryPath}`);
E('ERR_STDERR_CLOSE', 'process.stderr cannot be closed');
E('ERR_STDOUT_CLOSE', 'process.stdout cannot be closed');
E('ERR_HTTP_TRAILER_INVALID',
'Trailers are invalid with this transfer encoding');
E('ERR_UNKNOWN_BUILTIN_MODULE', (id) => `No such built-in module: ${id}`);
E('ERR_UNKNOWN_SIGNAL', (signal) => `Unknown signal: ${signal}`);
E('ERR_UNKNOWN_STDIN_TYPE', 'Unknown stdin file type');
Expand Down
33 changes: 33 additions & 0 deletions test/parallel/test-http-server-de-chunked-trailer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
'use strict';
const common = require('../common');

// This test ensures that a Trailer header is set only when a chunked transfer
// encoding is used.

const assert = require('assert');
const http = require('http');

const server = http.createServer(common.mustCall(function(req, res) {
res.setHeader('Trailer', 'baz');
const trailerInvalidErr = {
code: 'ERR_HTTP_TRAILER_INVALID',
message: 'Trailers are invalid with this transfer encoding',
type: Error
};
assert.throws(() => res.writeHead(200, {'Content-Length': '2'}),
common.expectsError(trailerInvalidErr));
res.removeHeader('Trailer');
res.end('ok');
}));
server.listen(0, common.mustCall(() => {
http.get({ port: server.address().port }, common.mustCall((res) => {
assert.strictEqual(res.statusCode, 200);
let buf = '';
res.on('data', (chunk) => {
buf += chunk;
}).on('end', common.mustCall(() => {
assert.strictEqual(buf, 'ok');
}));
server.close();
}));
}));

0 comments on commit 80c9ef0

Please sign in to comment.