diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/handlers/echo_h.erl | 20 | ||||
-rw-r--r-- | test/req_SUITE.erl | 27 |
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). |