aboutsummaryrefslogtreecommitdiffstats
path: root/test/handlers/multipart_h.erl
blob: 1b9297b928ff1ceccb0ffb9c48eaedf9ce07f8f1 (plain) (blame)
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.