From bd91a3207f4376bd63a72f6c5b1ebabb11747634 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Sat, 5 Jan 2019 16:21:53 +0100 Subject: Don't send empty data chunks This was a bug in the case of HTTP/1.1 and an inconvenience in the case of HTTP/2. --- test/gun_SUITE.erl | 58 ++++++++++++++++++++++++++++++++++++++++++++---------- test/gun_test.erl | 11 +++++++++++ 2 files changed, 59 insertions(+), 10 deletions(-) (limited to 'test') diff --git a/test/gun_SUITE.erl b/test/gun_SUITE.erl index a7bb0f1..ba5b523 100644 --- a/test/gun_SUITE.erl +++ b/test/gun_SUITE.erl @@ -18,7 +18,9 @@ -import(ct_helper, [doc/1]). -import(ct_helper, [name/0]). +-import(gun_test, [init_origin/2]). -import(gun_test, [init_origin/3]). +-import(gun_test, [receive_all_from/2]). all() -> ct_helper:all(?MODULE). @@ -107,16 +109,41 @@ detect_owner_gone_ws(_) -> end, cowboy:stop_listener(Name). -shutdown_reason(_) -> - doc("The last connection failure must be propagated."), - {ok, Pid} = gun:open("localhost", 12345, #{retry => 0}), - Ref = monitor(process, Pid), - receive - {'DOWN', Ref, process, Pid, {shutdown, econnrefused}} -> - ok - after 200 -> - error(timeout) - end. +ignore_empty_data_http(_) -> + doc("When gun:data/4 is called with nofin and empty data, it must be ignored."), + {ok, OriginPid, OriginPort} = init_origin(tcp, http), + {ok, Pid} = gun:open("localhost", OriginPort), + {ok, http} = gun:await_up(Pid), + Ref = gun:put(Pid, "/", []), + gun:data(Pid, Ref, nofin, "hello "), + gun:data(Pid, Ref, nofin, ["", <<>>]), + gun:data(Pid, Ref, fin, "world!"), + Data = receive_all_from(OriginPid, 500), + Lines = binary:split(Data, <<"\r\n">>, [global]), + Zero = [Z || <<"0">> = Z <- Lines], + 1 = length(Zero), + gun:close(Pid). + +ignore_empty_data_http2(_) -> + doc("When gun:data/4 is called with nofin and empty data, it must be ignored."), + {ok, OriginPid, OriginPort} = init_origin(tcp, http2), + {ok, Pid} = gun:open("localhost", OriginPort, #{protocols => [http2]}), + {ok, http2} = gun:await_up(Pid), + timer:sleep(100), %% Give enough time for the handshake to fully complete. + Ref = gun:put(Pid, "/", []), + gun:data(Pid, Ref, nofin, "hello "), + gun:data(Pid, Ref, nofin, ["", <<>>]), + gun:data(Pid, Ref, fin, "world!"), + Data = receive_all_from(OriginPid, 500), + << + %% HEADERS frame. + Len1:24, 1, _:40, _:Len1/unit:8, + %% First DATA frame. + 6:24, 0, _:7, 0:1, _:32, "hello ", + %% Second and final DATA frame. + 6:24, 0, _:7, 1:1, _:32, "world!" + >> = Data, + gun:close(Pid). info(_) -> doc("Get info from the Gun connection."), @@ -261,6 +288,17 @@ retry_timeout(_) -> error(shutdown_too_late) end. +shutdown_reason(_) -> + doc("The last connection failure must be propagated."), + {ok, Pid} = gun:open("localhost", 12345, #{retry => 0}), + Ref = monitor(process, Pid), + receive + {'DOWN', Ref, process, Pid, {shutdown, econnrefused}} -> + ok + after 200 -> + error(timeout) + end. + transform_header_name(_) -> doc("The transform_header_name option allows changing the case of header names."), {ok, ListenSocket} = gen_tcp:listen(0, [binary, {active, false}]), diff --git a/test/gun_test.erl b/test/gun_test.erl index 14c70c3..e74fcd0 100644 --- a/test/gun_test.erl +++ b/test/gun_test.erl @@ -106,3 +106,14 @@ receive_from(Pid, Timeout) -> after Timeout -> error(timeout) end. + +receive_all_from(Pid, Timeout) -> + receive_all_from(Pid, Timeout, <<>>). + +receive_all_from(Pid, Timeout, Acc) -> + try + More = receive_from(Pid, Timeout), + receive_all_from(Pid, Timeout, <>) + catch error:timeout -> + Acc + end. -- cgit v1.2.3