From 977e9a38b4709a2bf81dbf1f7e3feff66c979c40 Mon Sep 17 00:00:00 2001 From: Franciszek Koltuniuk Date: Mon, 19 Jun 2023 11:33:02 +0200 Subject: [PATCH] http: fix for handling on boot timers headers and request This change is a fix for handling headersTimeout and requestTimeout that causes unexpected behavior if the HTTP server is started on boot: - the connections to the server can be closed immediately with the status HTTP 408 This issue usually happens on IoT or embedded devices where the reference timestamp (returned by uv_hrtime()) is counted since boot and can be smaller than the headersTimeout or the requestTimeout value. Additionally added performance improvement to process the list of connection only if one of the timers should be processed PR-URL: https://github.com/nodejs/node/pull/48291 Reviewed-By: Robert Nagy Reviewed-By: Benjamin Gruenbaum Reviewed-By: James M Snell Reviewed-By: Paolo Insogna Reviewed-By: Marco Ippolito Reviewed-By: Matteo Collina --- src/node_http_parser.cc | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/node_http_parser.cc b/src/node_http_parser.cc index fbab0e10f7c913..2849d3bee1ac83 100644 --- a/src/node_http_parser.cc +++ b/src/node_http_parser.cc @@ -1106,11 +1106,22 @@ void ConnectionsList::Expired(const FunctionCallbackInfo& args) { std::swap(headers_timeout, request_timeout); } + // On IoT or embedded devices the uv_hrtime() may return the timestamp + // that is smaller than configured timeout for headers or request + // to prevent subtracting two unsigned integers + // that can yield incorrect results we should check + // if the 'now' is bigger than the timeout for headers or request const uint64_t now = uv_hrtime(); const uint64_t headers_deadline = - headers_timeout > 0 ? now - headers_timeout : 0; + (headers_timeout > 0 && now > headers_timeout) ? now - headers_timeout + : 0; const uint64_t request_deadline = - request_timeout > 0 ? now - request_timeout : 0; + (request_timeout > 0 && now > request_timeout) ? now - request_timeout + : 0; + + if (headers_deadline == 0 && request_deadline == 0) { + return args.GetReturnValue().Set(Array::New(isolate, 0)); + } auto iter = list->active_connections_.begin(); auto end = list->active_connections_.end();