aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/handlers/echo_h.erl20
-rw-r--r--test/req_SUITE.erl27
2 files changed, 46 insertions, 1 deletions
diff --git a/test/handlers/echo_h.erl b/test/handlers/echo_h.erl
index a116442..ec37a66 100644
--- a/test/handlers/echo_h.erl
+++ b/test/handlers/echo_h.erl
@@ -46,6 +46,19 @@ echo(<<"read_urlencoded_body">>, Req0, Opts) ->
_ -> cowboy_req:read_urlencoded_body(Req0)
end,
{ok, cowboy_req:reply(200, #{}, value_to_iodata(Body), Req), Opts};
+echo(<<"read_and_match_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_and_match_urlencoded_body([], Req0, Opts);
+ <<"/crash", _/bits>> -> cowboy_req:read_and_match_urlencoded_body([], Req0, Opts);
+ _ -> cowboy_req:read_and_match_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});
@@ -61,7 +74,12 @@ echo(<<"match">>, Req, Opts) ->
Fields = [binary_to_atom(F, latin1) || F <- Fields0],
Value = case Type of
<<"qs">> -> cowboy_req:match_qs(Fields, Req);
- <<"cookies">> -> cowboy_req:match_cookies(Fields, Req)
+ <<"cookies">> -> cowboy_req:match_cookies(Fields, Req);
+ <<"body_qs">> ->
+ %% Note that the Req should not be discarded but for the
+ %% purpose of this test this has no ill impacts.
+ {ok, Match, _} = cowboy_req:read_and_match_urlencoded_body(Fields, Req),
+ Match
end,
{ok, cowboy_req:reply(200, #{}, value_to_iodata(Value), Req), Opts};
echo(What, Req, Opts) ->
diff --git a/test/req_SUITE.erl b/test/req_SUITE.erl
index 9042f54..6ca4521 100644
--- a/test/req_SUITE.erl
+++ b/test/req_SUITE.erl
@@ -564,6 +564,33 @@ do_read_urlencoded_body_too_long(Path, Body, Config) ->
end,
gun:close(ConnPid).
+read_and_match_urlencoded_body(Config) ->
+ doc("Read and match an application/x-www-form-urlencoded request body."),
+ <<"#{}">> = do_body("POST", "/match/body_qs", [], "a=b&c=d", Config),
+ <<"#{a => <<\"b\">>}">> = do_body("POST", "/match/body_qs/a", [], "a=b&c=d", Config),
+ <<"#{c => <<\"d\">>}">> = do_body("POST", "/match/body_qs/c", [], "a=b&c=d", Config),
+ <<"#{a => <<\"b\">>,c => <<\"d\">>}">>
+ = do_body("POST", "/match/body_qs/a/c", [], "a=b&c=d", Config),
+ <<"#{a => <<\"b\">>,c => true}">> = do_body("POST", "/match/body_qs/a/c", [], "a=b&c", Config),
+ <<"#{a => true,c => <<\"d\">>}">> = do_body("POST", "/match/body_qs/a/c", [], "a&c=d", Config),
+ %% Ensure match errors result in a 400 response.
+ {400, _} = do_body_error("POST", "/match/body_qs/a/c", [], "a=b", Config),
+ %% Ensure parse errors result in a 400 response.
+ {400, _} = do_body_error("POST", "/match/body_qs", [], "%%%%%", Config),
+ %% Send a 10MB body, larger than the default length, to ensure a crash occurs.
+ ok = do_read_urlencoded_body_too_large(
+ "/no-opts/read_and_match_urlencoded_body",
+ string:chars($a, 10000000), Config),
+ %% We read any length for at most 1 second.
+ %%
+ %% The body is sent twice, first with nofin, then wait 1.1 second, then again with fin.
+ %% We expect the handler to crash because read_and_match_urlencoded_body expects the full body.
+ ok = do_read_urlencoded_body_too_long(
+ "/crash/read_and_match_urlencoded_body/period", <<"abc">>, Config),
+ %% The timeout value is set too low on purpose to ensure a crash occurs.
+ ok = do_read_body_timeout("/opts/read_and_match_urlencoded_body/timeout", <<"abc">>, Config),
+ ok.
+
multipart(Config) ->
doc("Multipart request body."),
do_multipart("/multipart", Config).