GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||
GeezerVison is showing github.com — http: frame client requests that carry a payload by zeexzeex · Pull Request #65512 · nodejs/node Conversation
Contributor
A client request whose method defaults to no chunked encoding ( const req = http.request({ method: 'DELETE', port }); req.write('PUT /admin HTTP/1.1\r\n\r\n'); req.end(); On the wire this produces a message with no framing headers followed by the payload, which the peer parses as a second request. Such requests are now framed like any other: Three cases deliberately keep the previous behaviour:
The last one needs more than Tests
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Collaborator
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page.
|
There was an error while loading. Please reload this page.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@ ## main #65512 +/- ## ======================================= Coverage 89.95% 89.96% ======================================= Files 757 757 Lines 258080 258089 +9 Branches 48933 48932 -1 ======================================= + Hits 232168 232194 +26 + Misses 16971 16966 -5 + Partials 8941 8929 -12
🚀 New features to boost your workflow:
|
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
CI is red on What happens The test opens a client request, pipes a body into it, and destroys the source before EOF. It then asserts on the error the server side sees: pipeline(req, res, common.mustCall((err) => { assert.strictEqual(err?.code, 'ERR_STREAM_PREMATURE_CLOSE'); })); Before this PR the request carried neither Why I think the new code is correct Once a request is declared chunked, aborting it mid-body is a transport-level failure, so I ran the full |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
A client request whose method defaults to no chunked encoding (GET, HEAD, DELETE, OPTIONS, TRACE) skipped both Content-Length and Transfer-Encoding even when a payload was written. The payload was still sent, so the peer read those bytes as the start of the next request, which allows request smuggling. Frame such requests like any other: use Content-Length when the length is known and a chunked Transfer-Encoding when it is not. Server responses and requests with no payload keep the previous behaviour, and CONNECT is left untouched because its payload is tunnelled data that must not be re-framed. Headers can be rendered before anything is written, for example when the headers are passed as an array or an Expect header is set. Track whether a payload write actually happened so that case is not mistaken for a body of unknown length. The two known_issues tests covering this now pass and move to parallel. They also asserted a response body for HEAD, which cannot have one, and compared buffers with strictEqual, so both are corrected in the move. Fixes: nodejs#27880 Refs: nodejs#34066 Refs: nodejs#60718 Signed-off-by: Avocado <[email protected]>
A client request that writes a payload is now framed with a chunked Transfer-Encoding. When the body source is destroyed before EOF the request ends without its terminating chunk, so the peer resets the connection instead of seeing a clean close, and the echoed response fails with ECONNRESET rather than ERR_STREAM_PREMATURE_CLOSE. Signed-off-by: Avocado <[email protected]>
A client request that carries a payload is framed with Content-Length or a chunked Transfer-Encoding, which is decided from the payload flag set when a write reaches the message. The fast path for a known-length end() renders the headers itself without going through that write, so the flag was still unset and such requests were framed as if they had no payload. Set the flag there as well, so a request whose whole payload is passed to end() is framed like any other. The pipeline test aborts a request body once the echoed response has been received. Chunked writes are now coalesced, so the response arrives as a single data event and counting events never reaches the abort. Count the received bytes instead, the way the neighbouring case already does. Signed-off-by: Avocado <[email protected]>
c7cdfa0 to
3cca48d
Compare
|
GitHub has detected one or more conflicts in this PR. If you would like to keep this PR active, please rebase the branch in this PR according to the Pull requests documentation. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
No content length on DELETE and OPTIONS
There was an error while loading. Please reload this page.