Error if message is bigger than Content-Length#39133
Error if message is bigger than Content-Length#39133betochf wants to merge 12 commits intonodejs:mainfrom
Conversation
lib/_http_outgoing.js
Outdated
| ERR_STREAM_NULL_VALUES, | ||
| ERR_STREAM_DESTROYED | ||
| ERR_STREAM_DESTROYED, | ||
| ERR_CONTENT_LENGTH_HEADER |
There was a problem hiding this comment.
| ERR_CONTENT_LENGTH_HEADER | |
| ERR_CONTENT_LENGTH_MISMATCH, |
There was a problem hiding this comment.
nit: Could this list also be sorted in alphabetical order?
There was a problem hiding this comment.
Ok, thanks for the feedback, would make the changes
ronag
left a comment
There was a problem hiding this comment.
Would also be nice if you check content length in .end() to make sure not to few bytes have been written as well.
|
Unrelated documentation changes in |
|
Hey @ronag for .end(), how many bytes would be a good amount so the error is not triggered? |
If it doesn’t match content length then error |
lib/_http_outgoing.js
Outdated
| function storeHeader(self, state, key, value, validate) { | ||
| if (validate) | ||
| validateHeaderValue(key, value); | ||
| if (key === 'Content-Length') { |
There was a problem hiding this comment.
| if (key === 'Content-Length') { | |
| if (key.toLowerCase() === 'content-length') { |
There was a problem hiding this comment.
https://nodejs.org/es/docs/guides/anatomy-of-an-http-transaction/
It's important to note here that all headers are represented in lower-case only, regardless of how the client actually sent them. This simplifies the task of parsing headers for whatever purpose.
|
|
||
| if (name === 'content-length') { | ||
| this._contentLength = NumberParseInt(value); | ||
| } |
There was a problem hiding this comment.
Oh sorry, shouldn't be there, my mistake
There was a problem hiding this comment.
I checked the code again and store header is not enough, the Content-length is not set when setHeader is used... I think it happens because it never goes throw processHeader
There was a problem hiding this comment.
Putting inside the validation function is wrong though.
There was a problem hiding this comment.
It seemed right sorry, I'll create a new function for the validating the content length
ronag
left a comment
There was a problem hiding this comment.
A lot of unrelated doc changes...
|
@betochf Could you please rebase and resolve the merge conflicts? |
|
@RaisinTen done, it was an error in the Doc |
| let headers = this[kOutHeaders]; | ||
| if (headers === null) | ||
| this[kOutHeaders] = headers = ObjectCreate(null); | ||
|
|
There was a problem hiding this comment.
+1. By the way, are changes in doc/api/errors.md also required? It seems like most of them are unrelated to an issue as well.
| } | ||
|
|
||
| if (msg._contentLength) { | ||
| if (msg[kBytesWritten] > msg._contentLength) { |
There was a problem hiding this comment.
You can combine these two if statements
| if (msg[kBytesWritten] > msg._contentLength) { | ||
| throw new ERR_CONTENT_LENGTH_MISMATCH(msg._contentLength, msg[kBytesWritten]); | ||
| } | ||
| } |
There was a problem hiding this comment.
Why is this check needed if you already have it below?
|
@ronag I did the changes... which other tests should I try? |
|
I think 3 tests should be added at least:
|
|
|
||
| const kCorked = Symbol('corked'); | ||
|
|
||
| const kBytesWritten = Symbol ('bytes'); |
There was a problem hiding this comment.
| const kBytesWritten = Symbol ('bytes'); | |
| const kBytesWritten = Symbol('bytes'); |
| } | ||
|
|
||
| const byteCount = (this[kBytesWritten] + chunk.length); | ||
| if (this._contentLength && (byteCount) !== this._contentLength) { |
There was a problem hiding this comment.
| if (this._contentLength && (byteCount) !== this._contentLength) { | |
| if (this._contentLength !== undefined && (byteCount) !== this._contentLength) { |
| } | ||
| return msg; | ||
| }, TypeError); | ||
| E('ERR_INVALID_CONTENT_LENGTH', function(size) { |
There was a problem hiding this comment.
ERR_INVALID_ARG_VALUE could be used instead.
| this.socket.cork(); | ||
| } | ||
|
|
||
| const byteCount = (this[kBytesWritten] + chunk.length); |
There was a problem hiding this comment.
This may not be entirely accurate in every case due to content encoding. For instance, if I pass in w.end('afef', 'hex'), I'm only writing 2 bytes. The calculation here needs to take into consideration the encoding and the actual byte length.
| let msg; | ||
| if (byteCount < contentLength) { | ||
| msg = 'less'; | ||
| } else msg = 'more'; |
There was a problem hiding this comment.
| let msg; | |
| if (byteCount < contentLength) { | |
| msg = 'less'; | |
| } else msg = 'more'; | |
| const msg = byteCount < contentLength ? 'less' : 'more'; |
|
Thanks for the PR This error was introduced in #44378 and is present in Node >= 16.18.0. (https://nodejs.org/api/http.html#responsestrictcontentlength) |
Pr for issue #39041
The test for the changes is very simple, it just contains a 200 request with a header specifying the "Content-Lenght", in this case with a size of 2 bytes, with a response of 4 so the error could be triggered.
tests: