0
Fork 0
mirror of https://github.com/ninenines/cowboy.git synced 2025-07-14 12:20:24 +00:00

Update the multipart reading interface

Now named read_part/read_part_body, with a verb indicating action.
This commit is contained in:
Loïc Hoguin 2016-08-10 15:09:04 +02:00
parent ae95e87eb1
commit aa6f2ab5a4
5 changed files with 38 additions and 36 deletions

View file

@ -6,8 +6,8 @@
-export([init/2]). -export([init/2]).
init(Req, Opts) -> init(Req, Opts) ->
{ok, Headers, Req2} = cowboy_req:part(Req), {ok, Headers, Req2} = cowboy_req:read_part(Req),
{ok, Data, Req3} = cowboy_req:part_body(Req2), {ok, Data, Req3} = cowboy_req:read_part_body(Req2),
{file, <<"inputfile">>, Filename, ContentType, _TE} {file, <<"inputfile">>, Filename, ContentType, _TE}
= cow_multipart:form_data(Headers), = cow_multipart:form_data(Headers),
io:format("Received file ~p of content-type ~p as follow:~n~p~n~n", io:format("Received file ~p of content-type ~p as follow:~n~p~n~n",

View file

@ -50,10 +50,10 @@
-export([read_urlencoded_body/2]). -export([read_urlencoded_body/2]).
%% Multipart. %% Multipart.
-export([part/1]). %% @todo read_part? -export([read_part/1]).
-export([part/2]). %% @todo read_part? -export([read_part/2]).
-export([part_body/1]). %% @todo read_part_body? -export([read_part_body/1]).
-export([part_body/2]). %% @todo read_part_body? -export([read_part_body/2]).
%% Response. %% Response.
-export([set_resp_cookie/3]). -export([set_resp_cookie/3]).
@ -71,7 +71,9 @@
-export([reply/4]). -export([reply/4]).
-export([stream_reply/2]). -export([stream_reply/2]).
-export([stream_reply/3]). -export([stream_reply/3]).
%% @todo stream_reply/2 (nofin)
-export([stream_body/3]). -export([stream_body/3]).
%% @todo stream_event/2,3
-export([push/3]). -export([push/3]).
-export([push/4]). -export([push/4]).
@ -438,32 +440,32 @@ read_urlencoded_body(Req0, Opts) ->
%% Multipart. %% Multipart.
-spec part(Req) -spec read_part(Req)
-> {ok, cow_multipart:headers(), Req} | {done, Req} -> {ok, cow_multipart:headers(), Req} | {done, Req}
when Req::req(). when Req::req().
part(Req) -> read_part(Req) ->
part(Req, #{length => 64000, period => 5000}). read_part(Req, #{length => 64000, period => 5000}).
-spec part(Req, body_opts()) -spec read_part(Req, body_opts())
-> {ok, cow_multipart:headers(), Req} | {done, Req} -> {ok, cow_multipart:headers(), Req} | {done, Req}
when Req::req(). when Req::req().
part(Req, Opts) -> read_part(Req, Opts) ->
case maps:is_key(multipart, Req) of case maps:is_key(multipart, Req) of
true -> true ->
{Data, Req2} = stream_multipart(Req, Opts), {Data, Req2} = stream_multipart(Req, Opts),
part(Data, Opts, Req2); read_part(Data, Opts, Req2);
false -> false ->
part(init_multipart(Req), Opts) read_part(init_multipart(Req), Opts)
end. end.
part(Buffer, Opts, Req=#{multipart := {Boundary, _}}) -> read_part(Buffer, Opts, Req=#{multipart := {Boundary, _}}) ->
case cow_multipart:parse_headers(Buffer, Boundary) of case cow_multipart:parse_headers(Buffer, Boundary) of
more -> more ->
{Data, Req2} = stream_multipart(Req, Opts), {Data, Req2} = stream_multipart(Req, Opts),
part(<< Buffer/binary, Data/binary >>, Opts, Req2); read_part(<< Buffer/binary, Data/binary >>, Opts, Req2);
{more, Buffer2} -> {more, Buffer2} ->
{Data, Req2} = stream_multipart(Req, Opts), {Data, Req2} = stream_multipart(Req, Opts),
part(<< Buffer2/binary, Data/binary >>, Opts, Req2); read_part(<< Buffer2/binary, Data/binary >>, Opts, Req2);
{ok, Headers, Rest} -> {ok, Headers, Rest} ->
%% @todo We may want headers as a map. Need to check the %% @todo We may want headers as a map. Need to check the
%% rules for multipart header parsing before taking a decision. %% rules for multipart header parsing before taking a decision.
@ -473,24 +475,24 @@ part(Buffer, Opts, Req=#{multipart := {Boundary, _}}) ->
{done, Req#{multipart => done}} {done, Req#{multipart => done}}
end. end.
-spec part_body(Req) -spec read_part_body(Req)
-> {ok, binary(), Req} | {more, binary(), Req} -> {ok, binary(), Req} | {more, binary(), Req}
when Req::req(). when Req::req().
part_body(Req) -> read_part_body(Req) ->
part_body(Req, #{}). read_part_body(Req, #{}).
-spec part_body(Req, body_opts()) -spec read_part_body(Req, body_opts())
-> {ok, binary(), Req} | {more, binary(), Req} -> {ok, binary(), Req} | {more, binary(), Req}
when Req::req(). when Req::req().
part_body(Req, Opts) -> read_part_body(Req, Opts) ->
case maps:is_key(multipart, Req) of case maps:is_key(multipart, Req) of
true -> true ->
part_body(<<>>, Opts, Req, <<>>); read_part_body(<<>>, Opts, Req, <<>>);
false -> false ->
part_body(init_multipart(Req), Opts) read_part_body(init_multipart(Req), Opts)
end. end.
part_body(Buffer, Opts, Req=#{multipart := {Boundary, _}}, Acc) -> read_part_body(Buffer, Opts, Req=#{multipart := {Boundary, _}}, Acc) ->
Length = maps:get(length, Opts, 8000000), Length = maps:get(length, Opts, 8000000),
case byte_size(Acc) > Length of case byte_size(Acc) > Length of
true -> true ->
@ -499,9 +501,9 @@ part_body(Buffer, Opts, Req=#{multipart := {Boundary, _}}, Acc) ->
{Data, Req2} = stream_multipart(Req, Opts), {Data, Req2} = stream_multipart(Req, Opts),
case cow_multipart:parse_body(<< Buffer/binary, Data/binary >>, Boundary) of case cow_multipart:parse_body(<< Buffer/binary, Data/binary >>, Boundary) of
{ok, Body} -> {ok, Body} ->
part_body(<<>>, Opts, Req2, << Acc/binary, Body/binary >>); read_part_body(<<>>, Opts, Req2, << Acc/binary, Body/binary >>);
{ok, Body, Rest} -> {ok, Body, Rest} ->
part_body(Rest, Opts, Req2, << Acc/binary, Body/binary >>); read_part_body(Rest, Opts, Req2, << Acc/binary, Body/binary >>);
done -> done ->
{ok, Acc, Req2}; {ok, Acc, Req2};
{done, Body} -> {done, Body} ->

View file

@ -14,7 +14,7 @@ init(Req0, State) ->
{ok, cowboy_req:reply(200, #{}, term_to_binary(Result), Req), State}. {ok, cowboy_req:reply(200, #{}, term_to_binary(Result), Req), State}.
acc_multipart(Req0, Acc) -> acc_multipart(Req0, Acc) ->
case cowboy_req:part(Req0) of case cowboy_req:read_part(Req0) of
{ok, Headers, Req1} -> {ok, Headers, Req1} ->
{ok, Body, Req} = stream_body(Req1, <<>>), {ok, Body, Req} = stream_body(Req1, <<>>),
acc_multipart(Req, [{Headers, Body}|Acc]); acc_multipart(Req, [{Headers, Body}|Acc]);
@ -23,7 +23,7 @@ acc_multipart(Req0, Acc) ->
end. end.
stream_body(Req0, Acc) -> stream_body(Req0, Acc) ->
case cowboy_req:part_body(Req0) of case cowboy_req:read_part_body(Req0) of
{more, Data, Req} -> {more, Data, Req} ->
stream_body(Req, << Acc/binary, Data/binary >>); stream_body(Req, << Acc/binary, Data/binary >>);
{ok, Data, Req} -> {ok, Data, Req} ->
@ -31,7 +31,7 @@ stream_body(Req0, Acc) ->
end. end.
skip_body_multipart(Req0, Acc) -> skip_body_multipart(Req0, Acc) ->
case cowboy_req:part(Req0) of case cowboy_req:read_part(Req0) of
{ok, Headers, Req} -> {ok, Headers, Req} ->
skip_body_multipart(Req, [Headers|Acc]); skip_body_multipart(Req, [Headers|Acc]);
{done, Req} -> {done, Req} ->
@ -39,7 +39,7 @@ skip_body_multipart(Req0, Acc) ->
end. end.
read_part2_multipart(Req0, Acc) -> read_part2_multipart(Req0, Acc) ->
case cowboy_req:part(Req0, #{length => 1, period => 1}) of case cowboy_req:read_part(Req0, #{length => 1, period => 1}) of
{ok, Headers, Req1} -> {ok, Headers, Req1} ->
{ok, Body, Req} = stream_body(Req1, <<>>), {ok, Body, Req} = stream_body(Req1, <<>>),
acc_multipart(Req, [{Headers, Body}|Acc]); acc_multipart(Req, [{Headers, Body}|Acc]);
@ -48,7 +48,7 @@ read_part2_multipart(Req0, Acc) ->
end. end.
read_part_body2_multipart(Req0, Acc) -> read_part_body2_multipart(Req0, Acc) ->
case cowboy_req:part(Req0) of case cowboy_req:read_part(Req0) of
{ok, Headers, Req1} -> {ok, Headers, Req1} ->
{ok, Body, Req} = stream_body2(Req1, <<>>), {ok, Body, Req} = stream_body2(Req1, <<>>),
acc_multipart(Req, [{Headers, Body}|Acc]); acc_multipart(Req, [{Headers, Body}|Acc]);
@ -57,7 +57,7 @@ read_part_body2_multipart(Req0, Acc) ->
end. end.
stream_body2(Req0, Acc) -> stream_body2(Req0, Acc) ->
case cowboy_req:part_body(Req0, #{length => 1, period => 1}) of case cowboy_req:read_part_body(Req0, #{length => 1, period => 1}) of
{more, Data, Req} -> {more, Data, Req} ->
stream_body(Req, << Acc/binary, Data/binary >>); stream_body(Req, << Acc/binary, Data/binary >>);
{ok, Data, Req} -> {ok, Data, Req} ->

View file

@ -9,9 +9,9 @@ init(Req, Opts) ->
{ok, cowboy_req:reply(200, #{}, term_to_binary(Result), Req2), Opts}. {ok, cowboy_req:reply(200, #{}, term_to_binary(Result), Req2), Opts}.
acc_multipart(Req, Acc) -> acc_multipart(Req, Acc) ->
case cowboy_req:part(Req) of case cowboy_req:read_part(Req) of
{ok, Headers, Req2} -> {ok, Headers, Req2} ->
{ok, Body, Req3} = cowboy_req:part_body(Req2), {ok, Body, Req3} = cowboy_req:read_part_body(Req2),
acc_multipart(Req3, [{Headers, Body}|Acc]); acc_multipart(Req3, [{Headers, Body}|Acc]);
{done, Req2} -> {done, Req2} ->
{lists:reverse(Acc), Req2} {lists:reverse(Acc), Req2}

View file

@ -9,7 +9,7 @@ init(Req, Opts) ->
{ok, cowboy_req:reply(200, Req2), Opts}. {ok, cowboy_req:reply(200, Req2), Opts}.
multipart(Req) -> multipart(Req) ->
case cowboy_req:part(Req) of case cowboy_req:read_part(Req) of
{ok, [{<<"content-length">>, BinLength}], Req2} -> {ok, [{<<"content-length">>, BinLength}], Req2} ->
Length = list_to_integer(binary_to_list(BinLength)), Length = list_to_integer(binary_to_list(BinLength)),
{Length, Req3} = stream_body(Req2, 0), {Length, Req3} = stream_body(Req2, 0),
@ -19,7 +19,7 @@ multipart(Req) ->
end. end.
stream_body(Req, N) -> stream_body(Req, N) ->
case cowboy_req:part_body(Req) of case cowboy_req:read_part_body(Req) of
{ok, Data, Req2} -> {ok, Data, Req2} ->
{N + byte_size(Data), Req2}; {N + byte_size(Data), Req2};
{more, Data, Req2} -> {more, Data, Req2} ->