Skip to content

Commit b716d09

Browse files
committed
fixup! http: add optimizeEmptyRequests server option
1 parent 2d617ab commit b716d09

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
@@ -3636,10 +3636,9 @@ changes:
36363636
when writing to an HTTP response which does not have a body.
36373637
**Default:** `false`.
36383638
* `optimizeEmptyRequests` {boolean} If set to `true`, requests without `Content-Length`
3639-
or `Transfer-Encoding` headers (indicating no body) will have their lifecycle events
3640-
immediately emitted. For `HEAD` and `GET` requests, this optimization is applied
3641-
regardless of headers. This improves performance for requests without bodies
3642-
across all HTTP methods.
3639+
or `Transfer-Encoding` headers (indicating no body) will be initialized with an
3640+
already-ended body stream, so they will never emit any stream events
3641+
(like `data` or `end`). You can use `req.readableEnded` to detect this case.
36433642
**Default:** `false`.
36443643
36453644
* `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
@@ -1111,24 +1111,14 @@ function parserOnIncoming(server, socket, state, req, keepAlive) {
11111111

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

11201116
if (shouldOptimize) {
11211117
// Fast processing where request "has" already emitted all lifecycle events.
11221118
// This avoids a lot of unnecessary overhead otherwise introduced by
11231119
// stream.Readable life cycle rules. The downside is that this will
11241120
// break some servers that read bodies for methods that don't have body headers.
1125-
req._dumped = true;
1126-
req._readableState.ended = true;
1127-
req._readableState.endEmitted = true;
1128-
req._readableState.destroyed = true;
1129-
req._readableState.closed = true;
1130-
req._readableState.closeEmitted = true;
1131-
1121+
req._dumpAndCloseReadable();
11321122
req._read();
11331123
}
11341124

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)