1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
%% This module reads a multipart body and echoes it back as an Erlang term.
-module(multipart_h).
-export([init/2]).
init(Req0, State) ->
{Result, Req} = case cowboy_req:binding(key, Req0) of
undefined -> acc_multipart(Req0, []);
<<"skip_body">> -> skip_body_multipart(Req0, []);
<<"read_part2">> -> read_part2_multipart(Req0, []);
<<"read_part_body2">> -> read_part_body2_multipart(Req0, [])
end,
{ok, cowboy_req:reply(200, #{}, term_to_binary(Result), Req), State}.
acc_multipart(Req0, Acc) ->
case cowboy_req:read_part(Req0) of
{ok, Headers, Req1} ->
{ok, Body, Req} = stream_body(Req1, <<>>),
acc_multipart(Req, [{Headers, Body}|Acc]);
{done, Req} ->
{lists:reverse(Acc), Req}
end.
stream_body(Req0, Acc) ->
case cowboy_req:read_part_body(Req0) of
{more, Data, Req} ->
stream_body(Req, << Acc/binary, Data/binary >>);
{ok, Data, Req} ->
{ok, << Acc/binary, Data/binary >>, Req}
end.
skip_body_multipart(Req0, Acc) ->
case cowboy_req:read_part(Req0) of
{ok, Headers, Req} ->
skip_body_multipart(Req, [Headers|Acc]);
{done, Req} ->
{lists:reverse(Acc), Req}
end.
read_part2_multipart(Req0, Acc) ->
case cowboy_req:read_part(Req0, #{length => 1, period => 1}) of
{ok, Headers, Req1} ->
{ok, Body, Req} = stream_body(Req1, <<>>),
acc_multipart(Req, [{Headers, Body}|Acc]);
{done, Req} ->
{lists:reverse(Acc), Req}
end.
read_part_body2_multipart(Req0, Acc) ->
case cowboy_req:read_part(Req0) of
{ok, Headers, Req1} ->
{ok, Body, Req} = stream_body2(Req1, <<>>),
acc_multipart(Req, [{Headers, Body}|Acc]);
{done, Req} ->
{lists:reverse(Acc), Req}
end.
stream_body2(Req0, Acc) ->
case cowboy_req:read_part_body(Req0, #{length => 1, period => 1}) of
{more, Data, Req} ->
stream_body(Req, << Acc/binary, Data/binary >>);
{ok, Data, Req} ->
{ok, << Acc/binary, Data/binary >>, Req}
end.
|