aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/src/guide/multipart.asciidoc2
-rw-r--r--doc/src/manual/cowboy_req.read_part.asciidoc4
-rw-r--r--examples/upload/src/upload_handler.erl2
-rw-r--r--src/cowboy_req.erl9
-rw-r--r--test/req_SUITE.erl22
5 files changed, 19 insertions, 20 deletions
diff --git a/doc/src/guide/multipart.asciidoc b/doc/src/guide/multipart.asciidoc
index 77d263a..756d3b4 100644
--- a/doc/src/guide/multipart.asciidoc
+++ b/doc/src/guide/multipart.asciidoc
@@ -102,7 +102,7 @@ multipart(Req0) ->
{data, _FieldName} ->
{ok, _Body, Req2} = cowboy_req:read_part_body(Req1),
Req2;
- {file, _FieldName, _Filename, _CType, _CTransferEncoding} ->
+ {file, _FieldName, _Filename, _CType} ->
stream_file(Req1)
end,
multipart(Req);
diff --git a/doc/src/manual/cowboy_req.read_part.asciidoc b/doc/src/manual/cowboy_req.read_part.asciidoc
index 0d689d8..fd21d4a 100644
--- a/doc/src/manual/cowboy_req.read_part.asciidoc
+++ b/doc/src/manual/cowboy_req.read_part.asciidoc
@@ -15,7 +15,7 @@ read_part(Req :: cowboy_req:req(), Opts)
-> {ok, Headers, Req} | {done, Req}
Opts :: cowboy_req:read_body_opts()
-Headers :: cow_multipart:headers()
+Headers :: #{binary() => binary()}
----
Read the next part of a multipart body.
@@ -70,7 +70,7 @@ to 5 seconds.
== Return value
An `ok` tuple is returned containing the next part's headers
-as a list of key/values.
+as a map.
A `done` tuple is returned if there are no more parts to read.
diff --git a/examples/upload/src/upload_handler.erl b/examples/upload/src/upload_handler.erl
index 08bca6f..5dbf08f 100644
--- a/examples/upload/src/upload_handler.erl
+++ b/examples/upload/src/upload_handler.erl
@@ -8,7 +8,7 @@
init(Req, Opts) ->
{ok, Headers, Req2} = cowboy_req:read_part(Req),
{ok, Data, Req3} = cowboy_req:read_part_body(Req2),
- {file, <<"inputfile">>, Filename, ContentType, _TE}
+ {file, <<"inputfile">>, Filename, ContentType}
= cow_multipart:form_data(Headers),
io:format("Received file ~p of content-type ~p as follow:~n~p~n~n",
[Filename, ContentType, Data]),
diff --git a/src/cowboy_req.erl b/src/cowboy_req.erl
index ffc6e12..ab77a68 100644
--- a/src/cowboy_req.erl
+++ b/src/cowboy_req.erl
@@ -463,7 +463,7 @@ read_part(Req) ->
read_part(Req, #{length => 64000, period => 5000}).
-spec read_part(Req, read_body_opts())
- -> {ok, cow_multipart:headers(), Req} | {done, Req}
+ -> {ok, #{binary() => binary()}, Req} | {done, Req}
when Req::req().
read_part(Req, Opts) ->
case maps:is_key(multipart, Req) of
@@ -482,9 +482,10 @@ read_part(Buffer, Opts, Req=#{multipart := {Boundary, _}}) ->
{more, Buffer2} ->
{Data, Req2} = stream_multipart(Req, Opts),
read_part(<< Buffer2/binary, Data/binary >>, Opts, Req2);
- {ok, Headers, Rest} ->
- %% @todo We may want headers as a map. Need to check the
- %% rules for multipart header parsing before taking a decision.
+ {ok, Headers0, Rest} ->
+ Headers = maps:from_list(Headers0),
+ %% Reject multipart content containing duplicate headers.
+ true = map_size(Headers) =:= length(Headers0),
{ok, Headers, Req#{multipart => {Boundary, Rest}}};
%% Ignore epilogue.
{done, _} ->
diff --git a/test/req_SUITE.erl b/test/req_SUITE.erl
index a2c040e..d155aa8 100644
--- a/test/req_SUITE.erl
+++ b/test/req_SUITE.erl
@@ -399,14 +399,13 @@ do_multipart(Path, Config) ->
{<<"content-type">>, <<"multipart/mixed; boundary=deadbeef">>}
], ReqBody, Config),
[
- {[{<<"content-type">>, <<"text/plain">>}], <<"Cowboy is an HTTP server.">>},
+ {#{<<"content-type">> := <<"text/plain">>}, <<"Cowboy is an HTTP server.">>},
{LargeHeaders, LargeBody}
] = binary_to_term(RespBody),
- %% @todo Multipart header order is currently undefined.
- [
- {<<"content-type">>, <<"application/octet-stream">>},
- {<<"x-custom">>, <<"value">>}
- ] = lists:sort(LargeHeaders),
+ #{
+ <<"content-type">> := <<"application/octet-stream">>,
+ <<"x-custom">> := <<"value">>
+ } = LargeHeaders,
ok.
read_part_skip_body(Config) ->
@@ -421,14 +420,13 @@ read_part_skip_body(Config) ->
{<<"content-type">>, <<"multipart/mixed; boundary=deadbeef">>}
], ReqBody, Config),
[
- [{<<"content-type">>, <<"text/plain">>}],
+ #{<<"content-type">> := <<"text/plain">>},
LargeHeaders
] = binary_to_term(RespBody),
- %% @todo Multipart header order is currently undefined.
- [
- {<<"content-type">>, <<"application/octet-stream">>},
- {<<"x-custom">>, <<"value">>}
- ] = lists:sort(LargeHeaders),
+ #{
+ <<"content-type">> := <<"application/octet-stream">>,
+ <<"x-custom">> := <<"value">>
+ } = LargeHeaders,
ok.
%% @todo When reading a multipart body, length and period