@@ -106,6 +106,8 @@ const onResponseFinishChannel = dc.channel('http.server.response.finish');
106106const kServerResponse = Symbol ( 'ServerResponse' ) ;
107107const kServerResponseStatistics = Symbol ( 'ServerResponseStatistics' ) ;
108108
109+ const kOptimizeEmptyRequests = Symbol ( 'OptimizeEmptyRequestsOption' ) ;
110+
109111const {
110112 hasObserver,
111113 startPerf,
@@ -452,6 +454,11 @@ function storeHTTPOptions(options) {
452454 validateInteger ( maxHeaderSize , 'maxHeaderSize' , 0 ) ;
453455 this . maxHeaderSize = maxHeaderSize ;
454456
457+ const optimizeEmptyRequests = options . optimizeEmptyRequests ;
458+ if ( optimizeEmptyRequests !== undefined )
459+ validateBoolean ( optimizeEmptyRequests , 'options.optimizeEmptyRequests' ) ;
460+ this [ kOptimizeEmptyRequests ] = optimizeEmptyRequests || false ;
461+
455462 const insecureHTTPParser = options . insecureHTTPParser ;
456463 if ( insecureHTTPParser !== undefined )
457464 validateBoolean ( insecureHTTPParser , 'options.insecureHTTPParser' ) ;
@@ -1102,6 +1109,29 @@ function parserOnIncoming(server, socket, state, req, keepAlive) {
11021109 } ) ;
11031110 }
11041111
1112+ // Check if we should optimize empty requests (those without Content-Length or Transfer-Encoding headers)
1113+ 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 ) ;
1119+
1120+ if ( shouldOptimize ) {
1121+ // Fast processing where request "has" already emitted all lifecycle events.
1122+ // This avoids a lot of unnecessary overhead otherwise introduced by
1123+ // stream.Readable life cycle rules. The downside is that this will
1124+ // 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+
1132+ req . _read ( ) ;
1133+ }
1134+
11051135 if ( socket . _httpMessage ) {
11061136 // There are already pending outgoing res, append.
11071137 state . outgoing . push ( res ) ;
0 commit comments