aboutsummaryrefslogtreecommitdiffstats
path: root/test/gun_SUITE.erl
diff options
context:
space:
mode:
Diffstat (limited to 'test/gun_SUITE.erl')
-rw-r--r--test/gun_SUITE.erl76
1 files changed, 71 insertions, 5 deletions
diff --git a/test/gun_SUITE.erl b/test/gun_SUITE.erl
index 6d1b00b..656158e 100644
--- a/test/gun_SUITE.erl
+++ b/test/gun_SUITE.erl
@@ -193,7 +193,7 @@ keepalive_infinity(_) ->
killed_streams_http(_) ->
doc("Ensure completed responses with a connection: close are not considered killed streams."),
{ok, _, OriginPort} = init_origin(tcp, http,
- fun (_, ClientSocket, ClientTransport) ->
+ fun (_, _, ClientSocket, ClientTransport) ->
{ok, _} = ClientTransport:recv(ClientSocket, 0, 1000),
ClientTransport:send(ClientSocket,
"HTTP/1.1 200 OK\r\n"
@@ -272,7 +272,7 @@ reply_to_http2(_) ->
do_reply_to(Protocol) ->
{ok, OriginPid, OriginPort} = init_origin(tcp, Protocol,
- fun(_, ClientSocket, ClientTransport) ->
+ fun(_, _, ClientSocket, ClientTransport) ->
{ok, _} = ClientTransport:recv(ClientSocket, 0, infinity),
ResponseData = case Protocol of
http ->
@@ -474,7 +474,7 @@ server_name_indication_default(_) ->
do_server_name_indication(Host, Expected, GunOpts) ->
Self = self(),
{ok, OriginPid, OriginPort} = init_origin(tls, http,
- fun(_, ClientSocket, _) ->
+ fun(_, _, ClientSocket, _) ->
{ok, Info} = ssl:connection_information(ClientSocket),
Msg = {sni_hostname, _} = lists:keyfind(sni_hostname, 1, Info),
Self ! Msg
@@ -527,7 +527,7 @@ do_shutdown_reason() ->
stream_info_http(_) ->
doc("Ensure the function gun:stream_info/2 works as expected for HTTP/1.1."),
{ok, OriginPid, OriginPort} = init_origin(tcp, http,
- fun(_, ClientSocket, ClientTransport) ->
+ fun(_, _, ClientSocket, ClientTransport) ->
%% Wait for the cancel signal.
receive cancel -> ok end,
%% Then terminate the stream.
@@ -574,7 +574,7 @@ stream_info_http(_) ->
stream_info_http2(_) ->
doc("Ensure the function gun:stream_info/2 works as expected for HTTP/2."),
{ok, OriginPid, OriginPort} = init_origin(tcp, http2,
- fun(_, _, _) -> receive disconnect -> ok end end),
+ fun(_, _, _, _) -> receive disconnect -> ok end end),
{ok, Pid} = gun:open("localhost", OriginPort, #{
event_handler => {gun_test_event_h, self()},
protocols => [http2]
@@ -604,6 +604,72 @@ supervise_false(_) ->
[] = [P || {_, P, _, _} <- supervisor:which_children(gun_sup), P =:= Pid],
ok.
+tls_handshake_error_gun_http2_init_retry_0(_) ->
+ doc("Ensure an early TLS connection close is propagated "
+ "to the user of the connection."),
+ %% The server will immediately close the connection upon
+ %% establishment so that the client's socket is down
+ %% before it attempts to initialise HTTP/2.
+ %%
+ %% We use 'http' for the server to skip the HTTP/2 init
+ %% but the client is connecting using 'http2'.
+ {ok, _, OriginPort} = init_origin(tls, http,
+ fun(_, _, ClientSocket, ClientTransport) ->
+ ClientTransport:close(ClientSocket)
+ end),
+ {ok, ConnPid} = gun:open("localhost", OriginPort, #{
+ event_handler => {gun_test_fun_event_h, #{
+ tls_handshake_end => fun(_, #{socket := _}) ->
+ %% We sleep right after the gun_tls:connect succeeds to make
+ %% sure the next call to the socket fails (as the socket
+ %% should be disconnected at that point by the server because
+ %% we are not sending a certificate). The call we want to fail
+ %% is the sending of the HTTP/2 preface in gun_http2:init.
+ timer:sleep(1000)
+ end
+ }},
+ protocols => [http2],
+ retry => 0,
+ transport => tls
+ }),
+ {error, {down, {shutdown, closed}}} = gun:await_up(ConnPid),
+ gun:close(ConnPid).
+
+tls_handshake_error_gun_http2_init_retry_1(_) ->
+ doc("Ensure an early TLS connection close is propagated "
+ "to the user of the connection and does not result "
+ "in an infinite connect loop."),
+ %% The server will immediately close the connection upon
+ %% establishment so that the client's socket is down
+ %% before it attempts to initialise HTTP/2.
+ %%
+ %% We use 'http' for the server to skip the HTTP/2 init
+ %% but the client is connecting using 'http2'.
+ %%
+ %% We immediately accept another connection to handle
+ %% the coming retry and close that connection again.
+ {ok, _, OriginPort} = init_origin(tls, http,
+ fun(_, ListenSocket, ClientSocket1, ClientTransport) ->
+ ClientTransport:close(ClientSocket1),
+ %% We immediately accept a second connection and close it again.
+ {ok, ClientSocket2t} = ssl:transport_accept(ListenSocket, 5000),
+ {ok, ClientSocket2} = ssl:handshake(ClientSocket2t, 5000),
+ ClientTransport:close(ClientSocket2)
+ end),
+ {ok, ConnPid} = gun:open("localhost", OriginPort, #{
+ event_handler => {gun_test_fun_event_h, #{
+ tls_handshake_end => fun(_, #{socket := _}) ->
+ %% See tls_handshake_error_gun_http2_init_retry_0 for details.
+ timer:sleep(1000)
+ end
+ }},
+ protocols => [http2],
+ retry => 1,
+ transport => tls
+ }),
+ {error, {down, {shutdown, closed}}} = gun:await_up(ConnPid),
+ gun:close(ConnPid).
+
tls_handshake_timeout(_) ->
doc("Ensure an integer value for tls_handshake_timeout is accepted."),
do_timeout(tls_handshake_timeout, 1000).