From 3da9a6eef9910946ec2500ea1f28faa71b85c855 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Mon, 20 Nov 2017 16:26:37 +0100 Subject: Add a test for early errors that occur on the request-line --- src/cowboy_http.erl | 6 ++++-- test/metrics_SUITE.erl | 52 ++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/src/cowboy_http.erl b/src/cowboy_http.erl index 246afbb..9b671a9 100644 --- a/src/cowboy_http.erl +++ b/src/cowboy_http.erl @@ -1108,8 +1108,10 @@ connection_hd_is_close(Conn) -> -spec error_terminate(cowboy:http_status(), #state{}, _) -> no_return(). error_terminate(StatusCode, State=#state{ref=Ref, peer=Peer, in_state=StreamState}, Reason) -> PartialReq = case StreamState of - #ps_request_line{} -> - #{}; + #ps_request_line{} -> #{ + ref => Ref, + peer => Peer + }; #ps_header{method=Method, path=Path, qs=Qs, version=Version, headers=ReqHeaders} -> #{ ref => Ref, diff --git a/test/metrics_SUITE.erl b/test/metrics_SUITE.erl index 1883014..3107447 100644 --- a/test/metrics_SUITE.erl +++ b/test/metrics_SUITE.erl @@ -19,6 +19,9 @@ -import(ct_helper, [doc/1]). -import(cowboy_test, [gun_open/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. @@ -76,11 +79,14 @@ init_routes(_) -> [ do_metrics_callback() -> fun(Metrics) -> - PidBin = case Metrics of - #{req := #{headers := #{<<"x-test-pid">> := P}}} -> P; - #{partial_req := #{headers := #{<<"x-test-pid">> := P}}} -> P + Pid = case Metrics of + #{req := #{headers := #{<<"x-test-pid">> := 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, - Pid = list_to_pid(binary_to_list(PidBin)), Pid ! {metrics, self(), Metrics}, ok end. @@ -311,6 +317,44 @@ do_early_error(Config) -> error(timeout) 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. stream_reply(Config) -> doc("Confirm metrics are correct for long polling."), -- cgit v1.2.3