aboutsummaryrefslogtreecommitdiffstats
path: root/test/handlers
diff options
context:
space:
mode:
Diffstat (limited to 'test/handlers')
-rw-r--r--test/handlers/echo_h.erl46
-rw-r--r--test/handlers/long_polling_h.erl1
-rw-r--r--test/handlers/loop_handler_body_h.erl7
-rw-r--r--test/handlers/multipart_h.erl65
-rw-r--r--test/handlers/resp_h.erl151
5 files changed, 254 insertions, 16 deletions
diff --git a/test/handlers/echo_h.erl b/test/handlers/echo_h.erl
index fd45c5f..fb7d8a8 100644
--- a/test/handlers/echo_h.erl
+++ b/test/handlers/echo_h.erl
@@ -12,10 +12,30 @@ init(Req, Opts) ->
echo_arg(Arg, Req, Opts)
end.
-echo(<<"body">>, Req0, Opts) ->
- {ok, Body, Req} = cowboy_req:read_body(Req0),
- cowboy_req:reply(200, #{}, Body, Req),
- {ok, Req, Opts};
+echo(<<"read_body">>, Req0, Opts) ->
+ case Opts of
+ #{crash := true} -> ct_helper:ignore(cowboy_req, read_body, 2);
+ _ -> ok
+ end,
+ {_, Body, Req} = case cowboy_req:path(Req0) of
+ <<"/full", _/bits>> -> read_body(Req0, <<>>);
+ <<"/opts", _/bits>> -> cowboy_req:read_body(Req0, Opts);
+ _ -> cowboy_req:read_body(Req0)
+ end,
+ {ok, cowboy_req:reply(200, #{}, Body, Req), Opts};
+echo(<<"read_urlencoded_body">>, Req0, Opts) ->
+ Path = cowboy_req:path(Req0),
+ case {Path, Opts} of
+ {<<"/opts", _/bits>>, #{crash := true}} -> ct_helper:ignore(cowboy_req, read_body, 2);
+ {_, #{crash := true}} -> ct_helper:ignore(cowboy_req, read_urlencoded_body, 2);
+ _ -> ok
+ end,
+ {ok, Body, Req} = case Path of
+ <<"/opts", _/bits>> -> cowboy_req:read_urlencoded_body(Req0, Opts);
+ <<"/crash", _/bits>> -> cowboy_req:read_urlencoded_body(Req0, Opts);
+ _ -> cowboy_req:read_urlencoded_body(Req0)
+ end,
+ {ok, cowboy_req:reply(200, #{}, value_to_iodata(Body), Req), Opts};
echo(<<"uri">>, Req, Opts) ->
Value = case cowboy_req:path_info(Req) of
[<<"origin">>] -> cowboy_req:uri(Req, #{host => undefined});
@@ -25,8 +45,7 @@ echo(<<"uri">>, Req, Opts) ->
[<<"set-port">>] -> cowboy_req:uri(Req, #{port => 123});
[] -> cowboy_req:uri(Req)
end,
- cowboy_req:reply(200, #{}, Value, Req),
- {ok, Req, Opts};
+ {ok, cowboy_req:reply(200, #{}, Value, Req), Opts};
echo(<<"match">>, Req, Opts) ->
[Type|Fields0] = cowboy_req:path_info(Req),
Fields = [binary_to_atom(F, latin1) || F <- Fields0],
@@ -34,13 +53,11 @@ echo(<<"match">>, Req, Opts) ->
<<"qs">> -> cowboy_req:match_qs(Fields, Req);
<<"cookies">> -> cowboy_req:match_cookies(Fields, Req)
end,
- cowboy_req:reply(200, #{}, value_to_iodata(Value), Req),
- {ok, Req, Opts};
+ {ok, cowboy_req:reply(200, #{}, value_to_iodata(Value), Req), Opts};
echo(What, Req, Opts) ->
F = binary_to_atom(What, latin1),
Value = cowboy_req:F(Req),
- cowboy_req:reply(200, #{}, value_to_iodata(Value), Req),
- {ok, Req, Opts}.
+ {ok, cowboy_req:reply(200, #{}, value_to_iodata(Value), Req), Opts}.
echo_arg(Arg0, Req, Opts) ->
F = binary_to_atom(cowboy_req:binding(key, Req), latin1),
@@ -52,8 +69,13 @@ echo_arg(Arg0, Req, Opts) ->
undefined -> cowboy_req:F(Arg, Req);
Default -> cowboy_req:F(Arg, Req, Default)
end,
- cowboy_req:reply(200, #{}, value_to_iodata(Value), Req),
- {ok, Req, Opts}.
+ {ok, cowboy_req:reply(200, #{}, value_to_iodata(Value), Req), Opts}.
+
+read_body(Req0, Acc) ->
+ case cowboy_req:read_body(Req0) of
+ {ok, Data, Req} -> {ok, << Acc/binary, Data/binary >>, Req};
+ {more, Data, Req} -> read_body(Req, << Acc/binary, Data/binary >>)
+ end.
value_to_iodata(V) when is_integer(V) -> integer_to_binary(V);
value_to_iodata(V) when is_atom(V) -> atom_to_binary(V, latin1);
diff --git a/test/handlers/long_polling_h.erl b/test/handlers/long_polling_h.erl
index 4f8e23f..17afa0a 100644
--- a/test/handlers/long_polling_h.erl
+++ b/test/handlers/long_polling_h.erl
@@ -14,6 +14,7 @@ init(Req, _) ->
{cowboy_loop, Req, 2, 5000, hibernate}.
info(timeout, Req, 0) ->
+ %% @todo Why 102?
{stop, cowboy_req:reply(102, Req), 0};
info(timeout, Req, Count) ->
erlang:send_after(200, self(), timeout),
diff --git a/test/handlers/loop_handler_body_h.erl b/test/handlers/loop_handler_body_h.erl
index 38ba2c0..e0ea41b 100644
--- a/test/handlers/loop_handler_body_h.erl
+++ b/test/handlers/loop_handler_body_h.erl
@@ -13,11 +13,10 @@ init(Req, _) ->
self() ! timeout,
{cowboy_loop, Req, undefined, 5000, hibernate}.
-info(timeout, Req, State) ->
- {ok, Body, Req2} = cowboy_req:read_body(Req),
+info(timeout, Req0, State) ->
+ {ok, Body, Req} = cowboy_req:read_body(Req0),
100000 = byte_size(Body),
- cowboy_req:reply(200, Req2),
- {stop, Req, State}.
+ {stop, cowboy_req:reply(200, Req), State}.
terminate(stop, _, _) ->
ok.
diff --git a/test/handlers/multipart_h.erl b/test/handlers/multipart_h.erl
new file mode 100644
index 0000000..1b9297b
--- /dev/null
+++ b/test/handlers/multipart_h.erl
@@ -0,0 +1,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.
diff --git a/test/handlers/resp_h.erl b/test/handlers/resp_h.erl
new file mode 100644
index 0000000..bb64906
--- /dev/null
+++ b/test/handlers/resp_h.erl
@@ -0,0 +1,151 @@
+%% This module echoes back the value the test is interested in.
+
+-module(resp_h).
+
+-export([init/2]).
+
+init(Req, Opts) ->
+ do(cowboy_req:binding(key, Req), Req, Opts).
+
+do(<<"set_resp_cookie3">>, Req0, Opts) ->
+ Req = case cowboy_req:binding(arg, Req0) of
+ undefined ->
+ cowboy_req:set_resp_cookie(<<"mycookie">>, "myvalue", Req0);
+ <<"multiple">> ->
+ Req1 = cowboy_req:set_resp_cookie(<<"mycookie">>, "myvalue", Req0),
+ cowboy_req:set_resp_cookie(<<"yourcookie">>, <<"yourvalue">>, Req1);
+ <<"overwrite">> ->
+ Req1 = cowboy_req:set_resp_cookie(<<"mycookie">>, "myvalue", Req0),
+ cowboy_req:set_resp_cookie(<<"mycookie">>, <<"overwrite">>, Req1)
+ end,
+ {ok, cowboy_req:reply(200, #{}, "OK", Req), Opts};
+do(<<"set_resp_cookie4">>, Req0, Opts) ->
+ Req = cowboy_req:set_resp_cookie(<<"mycookie">>, "myvalue", #{path => cowboy_req:path(Req0)}, Req0),
+ {ok, cowboy_req:reply(200, #{}, "OK", Req), Opts};
+do(<<"set_resp_header">>, Req0, Opts) ->
+ Req = cowboy_req:set_resp_header(<<"content-type">>, <<"text/plain">>, Req0),
+ {ok, cowboy_req:reply(200, #{}, "OK", Req), Opts};
+do(<<"set_resp_body">>, Req0, Opts) ->
+ Arg = cowboy_req:binding(arg, Req0),
+ Req1 = case Arg of
+ <<"sendfile">> ->
+ AppFile = code:where_is_file("cowboy.app"),
+ cowboy_req:set_resp_body({sendfile, 0, filelib:file_size(AppFile), AppFile}, Req0);
+ _ ->
+ cowboy_req:set_resp_body(<<"OK">>, Req0)
+ end,
+ Req = case Arg of
+ <<"override">> ->
+ cowboy_req:reply(200, #{}, <<"OVERRIDE">>, Req1);
+ _ ->
+ cowboy_req:reply(200, Req1)
+ end,
+ {ok, Req, Opts};
+do(<<"has_resp_header">>, Req0, Opts) ->
+ false = cowboy_req:has_resp_header(<<"content-type">>, Req0),
+ Req = cowboy_req:set_resp_header(<<"content-type">>, <<"text/plain">>, Req0),
+ true = cowboy_req:has_resp_header(<<"content-type">>, Req),
+ {ok, cowboy_req:reply(200, #{}, "OK", Req), Opts};
+do(<<"has_resp_body">>, Req0, Opts) ->
+ case cowboy_req:binding(arg, Req0) of
+ <<"sendfile">> ->
+ %% @todo Cases for sendfile. Note that sendfile 0 is unallowed.
+ false = cowboy_req:has_resp_body(Req0),
+ Req = cowboy_req:set_resp_body({sendfile, 0, 10, code:where_is_file("cowboy.app")}, Req0),
+ true = cowboy_req:has_resp_body(Req),
+ {ok, cowboy_req:reply(200, #{}, <<"OK">>, Req), Opts};
+ undefined ->
+ false = cowboy_req:has_resp_body(Req0),
+ Req = cowboy_req:set_resp_body(<<"OK">>, Req0),
+ true = cowboy_req:has_resp_body(Req),
+ {ok, cowboy_req:reply(200, #{}, Req), Opts}
+ end;
+do(<<"delete_resp_header">>, Req0, Opts) ->
+ false = cowboy_req:has_resp_header(<<"content-type">>, Req0),
+ Req1 = cowboy_req:set_resp_header(<<"content-type">>, <<"text/plain">>, Req0),
+ true = cowboy_req:has_resp_header(<<"content-type">>, Req1),
+ Req = cowboy_req:delete_resp_header(<<"content-type">>, Req1),
+ false = cowboy_req:has_resp_header(<<"content-type">>, Req),
+ {ok, cowboy_req:reply(200, #{}, "OK", Req), Opts};
+do(<<"reply2">>, Req0, Opts) ->
+ Req = case cowboy_req:binding(arg, Req0) of
+ <<"binary">> ->
+ cowboy_req:reply(<<"200 GOOD">>, Req0);
+ <<"error">> ->
+ ct_helper:ignore(cowboy_req, reply, 4),
+ cowboy_req:reply(ok, Req0);
+ <<"twice">> ->
+ ct_helper:ignore(cowboy_req, reply, 4),
+ Req1 = cowboy_req:reply(200, Req0),
+ cowboy_req:reply(200, Req1);
+ Status ->
+ cowboy_req:reply(binary_to_integer(Status), Req0)
+ end,
+ {ok, Req, Opts};
+do(<<"reply3">>, Req0, Opts) ->
+ Req = case cowboy_req:binding(arg, Req0) of
+ <<"error">> ->
+ ct_helper:ignore(cowboy_req, reply, 4),
+ cowboy_req:reply(200, ok, Req0);
+ Status ->
+ cowboy_req:reply(binary_to_integer(Status),
+ #{<<"content-type">> => <<"text/plain">>}, Req0)
+ end,
+ {ok, Req, Opts};
+do(<<"reply4">>, Req0, Opts) ->
+ Req = case cowboy_req:binding(arg, Req0) of
+ <<"error">> ->
+ ct_helper:ignore(erlang, iolist_size, 1),
+ cowboy_req:reply(200, #{}, ok, Req0);
+ Status ->
+ cowboy_req:reply(binary_to_integer(Status), #{}, <<"OK">>, Req0)
+ end,
+ {ok, Req, Opts};
+do(<<"stream_reply2">>, Req0, Opts) ->
+ Req = case cowboy_req:binding(arg, Req0) of
+ <<"binary">> ->
+ cowboy_req:stream_reply(<<"200 GOOD">>, Req0);
+ <<"error">> ->
+ ct_helper:ignore(cowboy_req, stream_reply, 3),
+ cowboy_req:stream_reply(ok, Req0);
+ Status ->
+ cowboy_req:stream_reply(binary_to_integer(Status), Req0)
+ end,
+ stream_body(Req),
+ {ok, Req, Opts};
+do(<<"stream_reply3">>, Req0, Opts) ->
+ Req = case cowboy_req:binding(arg, Req0) of
+ <<"error">> ->
+ ct_helper:ignore(cowboy_req, stream_reply, 3),
+ cowboy_req:stream_reply(200, ok, Req0);
+ Status ->
+ cowboy_req:stream_reply(binary_to_integer(Status),
+ #{<<"content-type">> => <<"text/plain">>}, Req0)
+ end,
+ stream_body(Req),
+ {ok, Req, Opts};
+do(<<"stream_body">>, Req, Opts) ->
+ %% Call stream_body without initiating streaming.
+ cowboy_req:stream_body(<<0:800000>>, fin, Req),
+ {ok, Req, Opts};
+do(<<"push">>, Req, Opts) ->
+ case cowboy_req:binding(arg, Req) of
+ <<"method">> ->
+ cowboy_req:push("/static/style.css", #{<<"accept">> => <<"text/css">>}, Req,
+ #{method => <<"HEAD">>});
+ <<"origin">> ->
+ cowboy_req:push("/static/style.css", #{<<"accept">> => <<"text/css">>}, Req,
+ #{scheme => <<"ftp">>, host => <<"127.0.0.1">>, port => 21});
+ <<"qs">> ->
+ cowboy_req:push("/static/style.css", #{<<"accept">> => <<"text/css">>}, Req,
+ #{qs => <<"server=cowboy&version=2.0">>});
+ _ ->
+ cowboy_req:push("/static/style.css", #{<<"accept">> => <<"text/css">>}, Req),
+ %% The text/plain mime is not defined by default, so a 406 will be returned.
+ cowboy_req:push("/static/plain.txt", #{<<"accept">> => <<"text/plain">>}, Req)
+ end,
+ {ok, cowboy_req:reply(200, Req), Opts}.
+
+stream_body(Req) ->
+ _ = [cowboy_req:stream_body(<<0:800000>>, nofin, Req) || _ <- lists:seq(1,9)],
+ cowboy_req:stream_body(<<0:800000>>, fin, Req).