feat(request-plugin): support multipart/form-data bodies - #412
Open
Taure wants to merge 1 commit into
Open
Conversation
Nova had no way to accept an uploaded file. The request plugin only knew about JSON and urlencoded bodies, and since should_read_body/1 ignored the content-type it drained a multipart body into `body` whenever decode_json_body was set - which every generated app sets globally - so reading the parts from a controller with cowboy_req:read_part/1 did not work either. Add a `read_multipart_body` option that reads the parts up front, putting regular fields under `params` and uploaded files under `files` as maps of name, filename, content_type and body. Parts are buffered in memory so a single part is capped at `max_file_size` (8 MB by default) and a part above the cap is answered with 413. A part with a malformed content-disposition is answered with 400. Without the option a multipart body is now left untouched, so a controller can stream the parts itself and hand the updated request back. Closes #411
|
One small suggestion, while reading a request (read_multipart_body), it can be pushed to callback function (of user configured) to avoid accumulating in memory. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #411
Nova had no way to accept an uploaded file. The request plugin only knew about JSON and urlencoded bodies, and since
should_read_body/1ignored the content-type it drained a multipart body intobodywheneverdecode_json_bodywas set - which every app generated byrebar3 nova newsets globally. That meant reading the parts from a controller withcowboy_req:read_part/1did not work either, because the body was already consumed by the time the controller ran.What this adds
A
read_multipart_bodyoption onnova_request_plugin:{pre_request, nova_request_plugin, #{read_multipart_body => true}}params, uploaded files underfilesas maps ofname,filename,content_typeandbody.max_file_size(8 MB by default, matching cowboy's own per-read default). Pass#{read_multipart_body => #{max_file_size => Bytes}}to change it. A part above the cap gets a413and the controller is never called.content-dispositiongets a400rather than crashing the handler.Behaviour change
A
multipart/form-databody is no longer drained intobodybydecode_json_body/read_urlencoded_body. Without the new option the body is left untouched, so a controller can stream the parts itself and hand the updated request back:Nothing was reading a multipart body out of
bodybefore this, since the plugin never parsed it.pre_request/4's spec now also admits the{stop, ...}return it could already produce.Tests
Five new eunit tests over a scripted
cowboy_req: fields plus files, chunked{more, ...}parts joined into one body,413on oversize,400on a malformed part, and one assertingread_bodyis never called for a multipart body.Docs
guides/plugins.mdgets the option-table row and a "File uploads" section covering both the plugin and the rawread_partroute.guides/controllers.mdgets a cross-link next to the outboundsendfilesection, which is where people currently land when looking for uploads.Checks
xrefclean,eunit362 tests / 0 failures,dialyzerclean,ex_docno warnings.