Skip to content

Commit 78a0e8f

Browse files
committed
fixup! http: add optimizeEmptyRequests server option
1 parent d7ee9ea commit 78a0e8f

File tree

4 files changed

+17
-16
lines changed

4 files changed

+17
-16
lines changed

doc/api/http.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3663,10 +3663,9 @@ changes:
36633663
when writing to an HTTP response which does not have a body.
36643664
**Default:** `false`.
36653665
* `optimizeEmptyRequests` {boolean} If set to `true`, requests without `Content-Length`
3666-
or `Transfer-Encoding` headers (indicating no body) will have their lifecycle events
3667-
immediately emitted. For `HEAD` and `GET` requests, this optimization is applied
3668-
regardless of headers. This improves performance for requests without bodies
3669-
across all HTTP methods.
3666+
or `Transfer-Encoding` headers (indicating no body) will be initialized with an
3667+
already-ended body stream, so they will never emit any stream events
3668+
(like `data` or `end`). You can use `req.readableEnded` to detect this case.
36703669
**Default:** `false`.
36713670
36723671
* `requestListener` {Function}

lib/_http_incoming.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,15 @@ function _addHeaderLineDistinct(field, value, dest) {
423423
}
424424
}
425425

426+
IncomingMessage.prototype._dumpAndCloseReadable = function _dumpAndCloseReadable() {
427+
this._dumped = true;
428+
this._readableState.ended = true;
429+
this._readableState.endEmitted = true;
430+
this._readableState.destroyed = true;
431+
this._readableState.closed = true;
432+
this._readableState.closeEmitted = true;
433+
};
434+
426435

427436
// Call this instead of resume() if we want to just
428437
// dump all the data to /dev/null

lib/_http_server.js

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1127,24 +1127,14 @@ function parserOnIncoming(server, socket, state, req, keepAlive) {
11271127

11281128
// Check if we should optimize empty requests (those without Content-Length or Transfer-Encoding headers)
11291129
const hasBodyHeaders = ('content-length' in req.headers) || ('transfer-encoding' in req.headers);
1130-
const isHeadOrGet = (req.method === 'HEAD' || req.method === 'GET');
1131-
1132-
// Apply optimization for all methods when optimizeEmptyRequests is enabled and there are no body headers
1133-
// For HEAD and GET methods, we optimize regardless of body headers for backward compatibility
1134-
const shouldOptimize = server[kOptimizeEmptyRequests] === true && (isHeadOrGet || !hasBodyHeaders);
1130+
const shouldOptimize = server[kOptimizeEmptyRequests] === true && !hasBodyHeaders;
11351131

11361132
if (shouldOptimize) {
11371133
// Fast processing where request "has" already emitted all lifecycle events.
11381134
// This avoids a lot of unnecessary overhead otherwise introduced by
11391135
// stream.Readable life cycle rules. The downside is that this will
11401136
// break some servers that read bodies for methods that don't have body headers.
1141-
req._dumped = true;
1142-
req._readableState.ended = true;
1143-
req._readableState.endEmitted = true;
1144-
req._readableState.destroyed = true;
1145-
req._readableState.closed = true;
1146-
req._readableState.closeEmitted = true;
1147-
1137+
req._dumpAndCloseReadable();
11481138
req._read();
11491139
}
11501140

test/parallel/test-http-server-optimize-empty-requests.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ const server = http.createServer({
1010
optimizeEmptyRequests: true
1111
}, (req, res) => {
1212
reqs++;
13+
req.on('data', common.mustNotCall());
14+
req.on('end', common.mustNotCall());
15+
1316
assert.strictEqual(req._dumped, true);
1417
assert.strictEqual(req._readableState.ended, true);
1518
assert.strictEqual(req._readableState.endEmitted, true);

0 commit comments

Comments
 (0)