Skip to content
This repository was archived by the owner on Apr 22, 2023. It is now read-only.

Commit 1fddc1f

Browse files
indutnytjfontaine
authored andcommitted
http: do not send 0\r\n\r\n in TE HEAD responses
When replying to a HEAD request, do not attempt to send the trailers and EOF sequence (`0\r\n\r\n`). The HEAD request MUST not have body. Quote from RFC: The presence of a message body in a response depends on both the request method to which it is responding and the response status code (Section 3.1.2). Responses to the HEAD request method (Section 4.3.2 of [RFC7231]) never include a message body because the associated response header fields (e.g., Transfer-Encoding, Content-Length, etc.), if present, indicate only what their values would have been if the request method had been GET (Section 4.3.1 of [RFC7231]). fix #8361 Reviewed-By: Timothy J Fontaine <tjfontaine@gmail.com>
1 parent 6e689ec commit 1fddc1f

2 files changed

Lines changed: 40 additions & 24 deletions

File tree

lib/http.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -945,6 +945,10 @@ OutgoingMessage.prototype.end = function(data, encoding) {
945945
if (encoding === 'hex' || encoding === 'base64')
946946
hot = false;
947947

948+
// Transfer-encoding: chunked responses to HEAD requests
949+
if (this._hasBody && this.chunkedEncoding)
950+
hot = false;
951+
948952
if (hot) {
949953
// Hot path. They're doing
950954
// res.writeHead();
@@ -982,7 +986,7 @@ OutgoingMessage.prototype.end = function(data, encoding) {
982986
}
983987

984988
if (!hot) {
985-
if (this.chunkedEncoding) {
989+
if (this._hasBody && this.chunkedEncoding) {
986990
ret = this._send('0\r\n' + this._trailer + '\r\n', 'ascii');
987991
} else {
988992
// Force a flush, HACK.

test/simple/test-http-head-request.js

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -26,32 +26,44 @@ var util = require('util');
2626

2727

2828
var body = 'hello world\n';
29+
var id = 0;
2930

30-
var server = http.createServer(function(req, res) {
31-
common.error('req: ' + req.method);
32-
res.writeHead(200, {'Content-Length': body.length});
33-
res.end();
34-
server.close();
35-
});
31+
function test(headers) {
32+
var port = common.PORT + id++;
33+
34+
var server = http.createServer(function(req, res) {
35+
console.error('req: %s headers: %j', req.method, headers);
36+
res.writeHead(200, headers);
37+
res.end();
38+
server.close();
39+
});
40+
41+
var gotEnd = false;
3642

37-
var gotEnd = false;
38-
39-
server.listen(common.PORT, function() {
40-
var request = http.request({
41-
port: common.PORT,
42-
method: 'HEAD',
43-
path: '/'
44-
}, function(response) {
45-
common.error('response start');
46-
response.on('end', function() {
47-
common.error('response end');
48-
gotEnd = true;
43+
server.listen(port, function() {
44+
var request = http.request({
45+
port: port,
46+
method: 'HEAD',
47+
path: '/'
48+
}, function(response) {
49+
console.error('response start');
50+
response.on('end', function() {
51+
console.error('response end');
52+
gotEnd = true;
53+
});
54+
response.resume();
4955
});
50-
response.resume();
56+
request.end();
5157
});
52-
request.end();
53-
});
5458

55-
process.on('exit', function() {
56-
assert.ok(gotEnd);
59+
process.on('exit', function() {
60+
assert.ok(gotEnd);
61+
});
62+
}
63+
64+
test({
65+
'Transfer-Encoding': 'chunked'
66+
});
67+
test({
68+
'Content-Length': body.length
5769
});

0 commit comments

Comments
 (0)