diff --git a/lib/_http_server.js b/lib/_http_server.js index c5681725ca5401..fed4f8f47a4e9f 100644 --- a/lib/_http_server.js +++ b/lib/_http_server.js @@ -111,6 +111,7 @@ const { startPerf, stopPerf, } = require('internal/perf/observe'); +const FixedQueue = require('internal/fixed_queue'); const STATUS_CODES = { 100: 'Continue', // RFC 7231 6.2.1 @@ -724,7 +725,7 @@ function connectionListenerInternal(server, socket) { onClose: null, onDrain: null, outgoing: [], - incoming: [], + incoming: new FixedQueue(), // `outgoingData` is an approximate amount of bytes queued through all // inactive responses. If more data than the high watermark is queued - we // need to pause TCP socket/HTTP parser, and wait until the data will be @@ -822,7 +823,7 @@ function socketOnClose(socket, state) { } function abortIncoming(incoming) { - while (incoming.length) { + while (!incoming.isEmpty()) { const req = incoming.shift(); req.destroy(new ConnResetException('aborted')); } @@ -1003,12 +1004,14 @@ function resOnFinish(req, res, socket, state, server) { }); } + const head = state.incoming.shift(); + // Usually the first incoming element should be our request. it may // be that in the case abortIncoming() was called that the incoming // array will be empty. - assert(state.incoming.length === 0 || state.incoming[0] === req); - - state.incoming.shift(); + if (head !== null && head !== req) { + throw new Error('Out of order response finish'); + } // If the user never called req.read(), and didn't pipe() or // .resume() or .on('data'), then we call req._dump() so that the