Skip to content

Commit

Permalink
http: fix for handling on boot timers headers and request
Browse files Browse the repository at this point in the history
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: #48291
Reviewed-By: Robert Nagy <ronagy@icloud.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Paolo Insogna <paolo@cowtech.it>
Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
  • Loading branch information
franciszek-koltuniuk-red authored and ruyadorno committed Sep 12, 2023
1 parent 9c1937c commit 977e9a3
Showing 1 changed file with 13 additions and 2 deletions.
15 changes: 13 additions & 2 deletions src/node_http_parser.cc
Expand Up @@ -1106,11 +1106,22 @@ void ConnectionsList::Expired(const FunctionCallbackInfo<Value>& 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();
Expand Down

0 comments on commit 977e9a3

Please sign in to comment.