Repository navigation
Add :max_message_size option to limit incoming message size - #44
GiuseppeSaluto wants to merge 2 commits into
Conversation
Reject messages over the limit while decoding: from a frame's declared length, from the accumulated size of a fragmented message, and while inflating with permessage-deflate (chunked :zlib.safeInflate/2). The default is 8_000_000 bytes; pass :infinity to disable the limit. Closes elixir-mint#43
Should we consider setting up a minimum limit that prevents things like these happening? |
|
Hello @whatyouhide! |
|
Hello @whatyouhide |
Closes #43
This adds a
:max_message_sizeoption toMint.WebSocket.new/5. When an incoming message goes over the limit,decode/2returns{:error, websocket, %Mint.WebSocketError{reason: :message_too_large}}.Where the limit is enforced
combine/3, before concatenating.:zlib.inflate/2is replaced by a:zlib.safeInflate/2loop that checks the inflated size after each chunk and stops as soon as it goes over the limit. A small compressed message can no longer inflate into an unbounded binary.All three use the same check (
Frame.check_message_size/2) and return the same error. The limit reachesPerMessageDeflatethrough the extension'sopts, so theExtensionbehaviour is unchanged.Default (breaking change)
As discussed in #43, the default is 8_000_000 bytes (same as
Plug.Parsers), with:infinityto opt out. Users receiving messages larger than 8 MB need to set the option, e.g.max_message_size: :infinity. This is visible in the Autobahn suite: cases 9.1.5/9.1.6/9.2.5/9.2.6 send 8 and 16 MiB messages, so the test client now passes:infinity.If you'd rather keep
:infinityas the default to avoid the breaking change, it's a one-line change in@default_max_message_size.Known limitations
safeInflatechunk, so up to one chunk (16 KB on OTP 27) may be inflated past the limit before stopping.:mode. Happy to add a check if you'd like.Tests
New tests in
test/mint/web_socket_test.exs, with a 100-byte limit:mix test(including Autobahn),mix dialyzer,mix format --check-formattedandmix compile --warnings-as-errorsall pass locally.