livery_multipart (livery v0.2.0)
View SourceStreaming multipart/form-data parser (RFC 7578).
Sits on the request body reader (livery_body) and works over both
streamed ({stream, _}) and buffered ({buffered, _}) bodies. Pull the
parts one at a time:
{ok, MP0} = livery_multipart:new(Req),
case livery_multipart:next_part(MP0, 5000) of
{part, #{name := Name, filename := File}, MP1} ->
%% drain this part's body incrementally
drain(MP1);
{done, _} -> ok
end.read_all/1,2 is a convenience that collects every part fully into
memory under the configured limits.
Security: the parser bounds all buffering (max_header_bytes,
max_header_count, max_parts, max_part_size, max_body) and never
touches the filesystem. A part's filename is returned verbatim; a
handler MUST confine/sanitize it before using it as a path.
Summary
Functions
Build a parser from a request. Reads the boundary from Content-Type.
new/1 with parser options.
Advance to the next part, returning its parsed metadata.
next_part/1 with an explicit per-chunk timeout.
Collect every part fully into memory under the configured limits.
read_all/1 with parser options.
Read the next chunk of the current part body.
Types
-opaque mp()
-type opts() :: #{part_timeout => timeout(), max_parts => pos_integer(), max_header_bytes => pos_integer(), max_header_count => pos_integer(), max_part_size => pos_integer(), max_body => pos_integer()}.
-type reason() :: malformed | {client_reset, term()} | timeout | {limit, max_parts | max_header_bytes | max_header_count | max_part_size | max_body}.
Functions
-spec new(livery_req:req()) -> {ok, mp()} | {error, not_multipart | no_boundary}.
Build a parser from a request. Reads the boundary from Content-Type.
-spec new(livery_req:req(), opts()) -> {ok, mp()} | {error, not_multipart | no_boundary}.
new/1 with parser options.
Advance to the next part, returning its parsed metadata.
next_part/1 with an explicit per-chunk timeout.
-spec read_all(livery_req:req()) -> {ok, [part_full()]} | {error, reason()}.
Collect every part fully into memory under the configured limits.
-spec read_all(livery_req:req(), opts()) -> {ok, [part_full()]} | {error, reason()}.
read_all/1 with parser options.
Read the next chunk of the current part body.