From 709e368708235f89b21372a9c6bd49df68e5bd41 Mon Sep 17 00:00:00 2001 From: Matteo Collina Date: Fri, 26 May 2023 14:38:24 +0200 Subject: [PATCH] http: send implicit headers on HEAD with no body If we respond to a HEAD request with a body, we ignore all writes. However, we must still include all implicit headers. Fixes a regressions introduced in https://github.com/nodejs/node/pull/47732. Signed-off-by: Matteo Collina PR-URL: https://github.com/nodejs/node/pull/48108 Reviewed-By: Colin Ihrig Reviewed-By: Robert Nagy Reviewed-By: Paolo Insogna Reviewed-By: Marco Ippolito --- lib/_http_outgoing.js | 22 +++++++-------- ...sponse-has-no-body-end-implicit-headers.js | 27 +++++++++++++++++++ ...test-http-head-response-has-no-body-end.js | 2 +- 3 files changed, 39 insertions(+), 12 deletions(-) create mode 100644 test/parallel/test-http-head-response-has-no-body-end-implicit-headers.js diff --git a/lib/_http_outgoing.js b/lib/_http_outgoing.js index ce875a9c92066e..bc57cd067507f7 100644 --- a/lib/_http_outgoing.js +++ b/lib/_http_outgoing.js @@ -883,17 +883,6 @@ function write_(msg, chunk, encoding, callback, fromEnd) { err = new ERR_STREAM_DESTROYED('write'); } - if (!msg._hasBody) { - if (msg[kRejectNonStandardBodyWrites]) { - throw new ERR_HTTP_BODY_NOT_ALLOWED(); - } else { - debug('This type of response MUST NOT have a body. ' + - 'Ignoring write() calls.'); - process.nextTick(callback); - return true; - } - } - if (err) { if (!msg.destroyed) { onError(msg, err, callback); @@ -926,6 +915,17 @@ function write_(msg, chunk, encoding, callback, fromEnd) { msg._implicitHeader(); } + if (!msg._hasBody) { + if (msg[kRejectNonStandardBodyWrites]) { + throw new ERR_HTTP_BODY_NOT_ALLOWED(); + } else { + debug('This type of response MUST NOT have a body. ' + + 'Ignoring write() calls.'); + process.nextTick(callback); + return true; + } + } + if (!fromEnd && msg.socket && !msg.socket.writableCorked) { msg.socket.cork(); process.nextTick(connectionCorkNT, msg.socket); diff --git a/test/parallel/test-http-head-response-has-no-body-end-implicit-headers.js b/test/parallel/test-http-head-response-has-no-body-end-implicit-headers.js new file mode 100644 index 00000000000000..5ebd9f8a90bd92 --- /dev/null +++ b/test/parallel/test-http-head-response-has-no-body-end-implicit-headers.js @@ -0,0 +1,27 @@ +'use strict'; +const common = require('../common'); +const http = require('http'); + +// This test is to make sure that when the HTTP server +// responds to a HEAD request with data to res.end, +// it does not send any body but the response is sent +// anyway. + +const server = http.createServer(function(req, res) { + res.end('FAIL'); // broken: sends FAIL from hot path. +}); +server.listen(0); + +server.on('listening', common.mustCall(function() { + const req = http.request({ + port: this.address().port, + method: 'HEAD', + path: '/' + }, common.mustCall(function(res) { + res.on('end', common.mustCall(function() { + server.close(); + })); + res.resume(); + })); + req.end(); +})); diff --git a/test/parallel/test-http-head-response-has-no-body-end.js b/test/parallel/test-http-head-response-has-no-body-end.js index 3e0e6cec240ba8..824a1bafe3a5e3 100644 --- a/test/parallel/test-http-head-response-has-no-body-end.js +++ b/test/parallel/test-http-head-response-has-no-body-end.js @@ -29,7 +29,7 @@ const http = require('http'); const server = http.createServer(function(req, res) { res.writeHead(200); - res.end(); + res.end('FAIL'); // broken: sends FAIL from hot path. }); server.listen(0);