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: nodejs#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 Ceres6 committed Aug 14, 2023
1 parent 25ff96d commit 1dab37d
Showing 1 changed file with 13 additions and 2 deletions.
15 changes: 13 additions & 2 deletions src/node_http_parser.cc
Original file line number Diff line number Diff line change
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 1dab37d

Please sign in to comment.