-
Notifications
You must be signed in to change notification settings - Fork 5.1k
node:http: enforce server headersTimeout and requestTimeout #33061
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
7d3011d
562f736
8bdce8f
97bac9b
24ce38e
16e099f
909c84a
68abcc6
d515950
012ff6e
b3af135
389db80
bfbc4d9
5b38098
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -65,8 +65,19 @@ namespace uWS | |||||||||||||||||||||
| HTTP_PARSER_ERROR_INVALID_EOF = 8, | ||||||||||||||||||||||
| HTTP_PARSER_ERROR_INVALID_METHOD = 9, | ||||||||||||||||||||||
| HTTP_PARSER_ERROR_INVALID_HEADER_TOKEN = 10, | ||||||||||||||||||||||
| /* Not a parse error: a node:http headersTimeout/requestTimeout receive | ||||||||||||||||||||||
| * deadline expired before the message was fully received. */ | ||||||||||||||||||||||
| HTTP_PARSER_ERROR_REQUEST_TIMEOUT = 11, | ||||||||||||||||||||||
| }; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| /* node:http receive phase of a socket (only meaningful when | ||||||||||||||||||||||
| * hasNodeReceiveTimeouts is set): Headers from connection (or the first | ||||||||||||||||||||||
| * byte of the next keep-alive message) until a message's header section | ||||||||||||||||||||||
| * is fully parsed, Body until its body is fully received, None while a | ||||||||||||||||||||||
| * handler/response is in flight or the keep-alive socket is idle after a | ||||||||||||||||||||||
| * completed exchange. CONNECT tunnels stream forever and have no phase. */ | ||||||||||||||||||||||
| enum class NodeReceivePhase : unsigned char { None, Headers, Body }; | ||||||||||||||||||||||
|
Comment on lines
+73
to
+79
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win Shorten the phase comment to the repository limit. This new block is 6 lines; keep only the durable invariant. Proposed cleanup- /* node:http receive phase of a socket (only meaningful when
- * hasNodeReceiveTimeouts is set): Headers from connection (or the first
- * byte of the next keep-alive message) until a message's header section
- * is fully parsed, Body until its body is fully received, None while a
- * handler/response is in flight or the keep-alive socket is idle after a
- * completed exchange. CONNECT tunnels stream forever and have no phase. */
+ /* node:http receive phase when hasNodeReceiveTimeouts is set.
+ * Headers lasts until parsed; Body until received; CONNECT/idle use None. */As per coding guidelines, “Keep code comments to 3 lines max.” 📝 Committable suggestion
Suggested change
🤖 Prompt for AI AgentsSource: Coding guidelines |
||||||||||||||||||||||
|
|
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| enum HTTPHeaderParserError: uint8_t { | ||||||||||||||||||||||
| HTTP_HEADER_PARSER_ERROR_NONE = 0, | ||||||||||||||||||||||
|
|
@@ -868,6 +879,15 @@ namespace uWS | |||||||||||||||||||||
| data[length + 1] = 'a'; /* Anything that is not \n, to trigger "invalid request" */ | ||||||||||||||||||||||
| req->ancientHttp = false; | ||||||||||||||||||||||
| for (;length;) { | ||||||||||||||||||||||
| /* node:http: a message whose request line begins here arrived in the | ||||||||||||||||||||||
| * packet onData is delivering, so its receive deadlines are measured | ||||||||||||||||||||||
| * from that packet's arrival. ConsumeMinimally only ever resumes a | ||||||||||||||||||||||
| * message buffered from an earlier packet, which keeps its own start. */ | ||||||||||||||||||||||
| if constexpr (!ConsumeMinimally) { | ||||||||||||||||||||||
| if (nodePacketTimestampMs) { | ||||||||||||||||||||||
| nodeMessageStartMs = nodePacketTimestampMs; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| auto result = getHeaders(data, data + length, req->headers, reserved, req->ancientHttp, isConnectRequest, useStrictMethodValidation, maxHeaderSize); | ||||||||||||||||||||||
| if(result.isError()) { | ||||||||||||||||||||||
| return result; | ||||||||||||||||||||||
|
|
@@ -1039,6 +1059,26 @@ namespace uWS | |||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| public: | ||||||||||||||||||||||
| /* True while a dispatched message still has body bytes outstanding | ||||||||||||||||||||||
| * (Content-Length not yet satisfied, or chunked body not terminated). */ | ||||||||||||||||||||||
| bool isReceivingHttpBody() const { | ||||||||||||||||||||||
| return remainingStreamingBytes != 0; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| /* True when incomplete request bytes are buffered, i.e. a message started | ||||||||||||||||||||||
| * arriving but its header section has not been fully parsed yet. */ | ||||||||||||||||||||||
| bool hasPartialRequest() const { | ||||||||||||||||||||||
| return fallback.length() > 0; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| /* node:http receive deadlines are absolute per message, measured from the | ||||||||||||||||||||||
| * message's first received byte. HttpContext::onData stamps the packet's | ||||||||||||||||||||||
| * arrival time here before parsing (0 = those deadlines are off), and the | ||||||||||||||||||||||
| * parser copies it into nodeMessageStartMs as each message's request line | ||||||||||||||||||||||
| * begins. See HttpContext::tryArmNodeReceiveTimeout. */ | ||||||||||||||||||||||
| uint64_t nodePacketTimestampMs = 0; | ||||||||||||||||||||||
| uint64_t nodeMessageStartMs = 0; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| HttpParserResult consumePostPadded(uint64_t maxHeaderSize, bool& isConnectRequest, bool requireHostHeader, bool useStrictMethodValidation, char *data, unsigned int length, void *user, void *reserved, MoveOnlyFunction<void *(void *, HttpRequest *)> &&requestHandler, MoveOnlyFunction<void *(void *, std::string_view, bool)> &&dataHandler) { | ||||||||||||||||||||||
| /* This resets BloomFilter by construction, but later we also reset it again. | ||||||||||||||||||||||
| * Optimize this to skip resetting twice (req could be made global) */ | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.