0
Fork 0
mirror of https://github.com/ninenines/cowboy.git synced 2025-07-14 12:20:24 +00:00

Add a test for early errors that occur on the request-line

This commit is contained in:
Loïc Hoguin 2017-11-20 16:26:37 +01:00
parent 92672b49af
commit 3da9a6eef9
No known key found for this signature in database
GPG key ID: 8A9DF795F6FED764
2 changed files with 52 additions and 6 deletions

View file

@ -1108,8 +1108,10 @@ connection_hd_is_close(Conn) ->
-spec error_terminate(cowboy:http_status(), #state{}, _) -> no_return(). -spec error_terminate(cowboy:http_status(), #state{}, _) -> no_return().
error_terminate(StatusCode, State=#state{ref=Ref, peer=Peer, in_state=StreamState}, Reason) -> error_terminate(StatusCode, State=#state{ref=Ref, peer=Peer, in_state=StreamState}, Reason) ->
PartialReq = case StreamState of PartialReq = case StreamState of
#ps_request_line{} -> #ps_request_line{} -> #{
#{}; ref => Ref,
peer => Peer
};
#ps_header{method=Method, path=Path, qs=Qs, #ps_header{method=Method, path=Path, qs=Qs,
version=Version, headers=ReqHeaders} -> #{ version=Version, headers=ReqHeaders} -> #{
ref => Ref, ref => Ref,

View file

@ -19,6 +19,9 @@
-import(ct_helper, [doc/1]). -import(ct_helper, [doc/1]).
-import(cowboy_test, [gun_open/1]). -import(cowboy_test, [gun_open/1]).
-import(cowboy_test, [gun_down/1]). -import(cowboy_test, [gun_down/1]).
-import(cowboy_test, [raw_open/1]).
-import(cowboy_test, [raw_send/2]).
-import(cowboy_test, [raw_recv_head/1]).
%% ct. %% ct.
@ -76,11 +79,14 @@ init_routes(_) -> [
do_metrics_callback() -> do_metrics_callback() ->
fun(Metrics) -> fun(Metrics) ->
PidBin = case Metrics of Pid = case Metrics of
#{req := #{headers := #{<<"x-test-pid">> := P}}} -> P; #{req := #{headers := #{<<"x-test-pid">> := P}}} ->
#{partial_req := #{headers := #{<<"x-test-pid">> := P}}} -> P list_to_pid(binary_to_list(P));
#{partial_req := #{headers := #{<<"x-test-pid">> := P}}} ->
list_to_pid(binary_to_list(P));
_ ->
whereis(early_error_metrics)
end, end,
Pid = list_to_pid(binary_to_list(PidBin)),
Pid ! {metrics, self(), Metrics}, Pid ! {metrics, self(), Metrics},
ok ok
end. end.
@ -311,6 +317,44 @@ do_early_error(Config) ->
error(timeout) error(timeout)
end. end.
early_error_request_line(Config) ->
case config(protocol, Config) of
http -> do_early_error_request_line(Config);
http2 -> doc("The callback early_error/5 is not currently used for HTTP/2.")
end.
do_early_error_request_line(Config) ->
doc("Confirm metrics are correct for an early_error response "
"that occurred on the request-line."),
%% Register the process in order to receive the metrics event.
register(early_error_metrics, self()),
%% Send a malformed request-line.
Client = raw_open(Config),
ok = raw_send(Client, <<"FOO bar\r\n">>),
{'HTTP/1.1', 400, _, Rest} = cow_http:parse_status_line(raw_recv_head(Client)),
{RespHeaders, _} = cow_http:parse_headers(Rest),
%% Receive the metrics and validate them.
receive
{metrics, From, Metrics} ->
%% Confirm the metadata is there as expected.
#{
ref := _,
pid := From,
streamid := 1,
reason := {connection_error, protocol_error, _},
partial_req := #{},
resp_status := 400,
resp_headers := ExpectedRespHeaders,
early_error_time := _,
resp_body_length := 0
} = Metrics,
ExpectedRespHeaders = maps:from_list(RespHeaders),
%% All good!
ok
after 1000 ->
error(timeout)
end.
%% This test is identical to normal GET except for the handler. %% This test is identical to normal GET except for the handler.
stream_reply(Config) -> stream_reply(Config) ->
doc("Confirm metrics are correct for long polling."), doc("Confirm metrics are correct for long polling."),