diff --git a/src/node_http_parser.cc b/src/node_http_parser.cc index 50d7f9e6916096..377c0637ea6c50 100644 --- a/src/node_http_parser.cc +++ b/src/node_http_parser.cc @@ -317,6 +317,7 @@ class Parser : public AsyncWrap, public StreamListener { num_fields_ = num_values_ = 0; headers_completed_ = false; chunk_extensions_nread_ = 0; + received_data_ = true; last_message_start_ = uv_hrtime(); allocator_.Reset(); url_.Reset(); @@ -723,6 +724,7 @@ class Parser : public AsyncWrap, public StreamListener { if (connectionsList != nullptr) { parser->connectionsList_ = connectionsList; + parser->received_data_ = false; // This protects from a DoS attack where an attacker establishes // the connection without sending any data on applications where @@ -1064,6 +1066,7 @@ class Parser : public AsyncWrap, public StreamListener { const char* current_buffer_data_; bool headers_completed_ = false; bool pending_pause_ = false; + bool received_data_ = false; uint64_t header_nread_ = 0; uint64_t chunk_extensions_nread_ = 0; uint64_t max_http_header_size_; @@ -1144,7 +1147,7 @@ void ConnectionsList::Idle(const FunctionCallbackInfo& args) { LocalVector result(isolate); result.reserve(list->all_connections_.size()); for (auto parser : list->all_connections_) { - if (parser->last_message_start_ == 0) { + if (parser->last_message_start_ == 0 || !parser->received_data_) { result.emplace_back(parser->object()); } } diff --git a/test/parallel/test-http-server-close-idle-connections-pre-request.js b/test/parallel/test-http-server-close-idle-connections-pre-request.js new file mode 100644 index 00000000000000..a9142b17348969 --- /dev/null +++ b/test/parallel/test-http-server-close-idle-connections-pre-request.js @@ -0,0 +1,23 @@ +'use strict'; + +const common = require('../common'); + +const { createServer } = require('http'); +const { createConnection } = require('net'); + +const server = createServer(common.mustNotCall()); + +server.listen(0, '127.0.0.1', common.mustCall(() => { + const port = server.address().port; + server.once('connection', common.mustCall(() => { + server.close(common.mustCall()); + server.closeIdleConnections(); + setTimeout(common.mustNotCall(), common.platformTimeout(1000)).unref(); + })); + + const socket = createConnection(port, '127.0.0.1'); + + socket.on('connect', common.mustCall()); + socket.on('close', common.mustCall()); + socket.on('error', () => {}); +}));