Repository navigation
feat: add max_*_size options - #67
kevinschweikert wants to merge 1 commit into
Conversation
| BodyFormat(BodyFormat) | ||
| SocketOpts(List(SocketOpt)) | ||
| Ipv6HostWithBrackets(Bool) | ||
| MaxHeaderSize(Dynamic) |
There was a problem hiding this comment.
Is there a better way to type this? the option takes either {bytes, N} or nolimit. So either a tuple or a single atom.
There was a problem hiding this comment.
It should be a new type rather than Dynamic, as it would be invalid for it to be values other than those two and Dynamic means anything.
There was a problem hiding this comment.
Fixed by introducing a private ErlMaxSize type
cd63814 to
89225df
Compare
lpil
left a comment
There was a problem hiding this comment.
Thank you!!! I've left a bunch of notes inline.
| /// The header of the response is longer than configured | ||
| HeaderTooLong(max_size: Int) | ||
| /// The responses `Content-Length` header exceeded the limit | ||
| ResponseBodyTooBig |
There was a problem hiding this comment.
Let's use the same format for both new error variants.
Perhaps HeaderToLarge and BodyTooLarge?
I don't think having the max size from the configuration is overly useful here. Is it possible to get the name of the header?
Could you change the documentation to these please:
One of the response headers was larger than
max_header_size.
The response body was larger than
max_body_size.
There was a problem hiding this comment.
I would propose ResponseHeaderTooLarge and ResponseBodyTooLarge to align with ResponseTimeout so that it is consistent with the existing naming scheme and it clearly says that the issue is the response and not the request.
I don't see a way to get the offending header because the max size is summed across all headers. the erlang error just returns the number of configured max bytes which is a bit redundant in our case.
| BodyFormat(BodyFormat) | ||
| SocketOpts(List(SocketOpt)) | ||
| Ipv6HostWithBrackets(Bool) | ||
| MaxHeaderSize(Dynamic) |
There was a problem hiding this comment.
It should be a new type rather than Dynamic, as it would be invalid for it to be values other than those two and Dynamic means anything.
| /// Max header size (cummulative) | ||
| /// | ||
| max_header_size: MaxSize, | ||
| /// Max body size | ||
| /// | ||
| max_body_size: MaxSize, |
There was a problem hiding this comment.
This documentation is very sparse, please add more detail.
There was a problem hiding this comment.
Done! I've used the same wording as OTP
| verify_tls: True, | ||
| follow_redirects: False, | ||
| timeout: 30_000, | ||
| max_header_size: Bytes(10_240), |
There was a problem hiding this comment.
Let's go for 2kb rather than 1kib.
There was a problem hiding this comment.
Just so you know i set the same default as httpc itself:
https://www.erlang.org/doc/apps/inets/httpc.html#request/5
max_header_size - Maximum total number of bytes allowed for the response headers (cumulative across all header lines). If the server sends headers exceeding this limit, the request fails with {error, {header_too_long, {max, MaxSize}}}.
The atom nolimit disables the check (not recommended).
Default is 10240 (same as the max_header_size configuration for httpd).
| follow_redirects: False, | ||
| timeout: 30_000, | ||
| max_header_size: Bytes(10_240), | ||
| max_body_size: Nolimit, |
There was a problem hiding this comment.
Is there a reason to ever permit no limit? Surely the same problem exists with the body, and a limit is always desired.
There was a problem hiding this comment.
Same here, this is the httpc default:
https://www.erlang.org/doc/apps/inets/httpc.html#request/5
max_body_size - Maximum number of bytes allowed for the response body. If the
Content-Lengthof the response exceeds this limit, the request fails with{error, body_too_big}.The atom
nolimitdisables the check.Default is
nolimit.
| Builder(..config, timeout:) | ||
| } | ||
|
|
||
| /// Maximum total number of bytes allowed for the response headers (cumulative across all header lines) |
There was a problem hiding this comment.
Wrap long lines please, and sentences end with a full-stop.
Please write the documentation in the style of the other builder functions, and include a description of what happens if it is exceeded.
Set the maximum size limit in bytes for the combination of all the headers of the response.
The default is 20000 bytes.
If a response's headers are larger than this limit then the XYZ error is returned.
| Builder(..config, max_header_size:) | ||
| } | ||
|
|
||
| /// Maximum number of bytes allowed for the response body. |
|
|
||
| ["header_size", size_bytes_str], _ -> { | ||
| let assert Ok(size_bytes) = int.parse(size_bytes_str) | ||
| let header = list.repeat("a", size_bytes) |> string.join("") |
There was a problem hiding this comment.
Use string.repeat please 🙏
This test checks only a single header, but the feature it across all headers, so verify that behaviour please.
There was a problem hiding this comment.
Ah i didn't know string.repeat existed! Fixed!
The tests are a bit tricky to write. I changed the implementation to return two headers so the cumulative behaviour can be tested. But the server itself also injects some headers like date, connection and content-length which are out of reach in the http handler. so the test has to assert with some overhead margins.
| ## Unreleased | ||
|
|
||
| - Fixed a bug where requests to IPv6 literal hosts would fail. | ||
| - Added `max_body_size` and `max_header_size` to the configuration options |
There was a problem hiding this comment.
Document the other additions too please, and sentences end with a full stop.
89225df to
81eaad0
Compare
|
@lpil i hope i adressed everything. Let me know if anything still needs changing! |
inets 9.7.2 introduced two new options: - max_body_size - max_header_size
81eaad0 to
291ae51
Compare
inets 9.7.2 introduced two new options:
The default configuration keeps the documented OTP defaults
Closes #66