aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2020-11-12 17:17:32 +0100
committerLoïc Hoguin <[email protected]>2020-11-12 17:17:32 +0100
commitd7a561c3743dc7391566d3e0d28d8cf910080786 (patch)
treef4db94c3fd62450ab7896f83e089f638898a96da
parent492c955819eec864e3f3ea2760d3ee7800851356 (diff)
downloadgun-d7a561c3743dc7391566d3e0d28d8cf910080786.tar.gz
gun-d7a561c3743dc7391566d3e0d28d8cf910080786.tar.bz2
gun-d7a561c3743dc7391566d3e0d28d8cf910080786.zip
Reset host/port/scheme/transport/intermediaries on disconnect
I've made some more test timeouts infinity in order to fix additional intermittent issues that popped up.
-rw-r--r--src/gun.erl34
-rw-r--r--test/rfc7231_SUITE.erl12
-rw-r--r--test/rfc7540_SUITE.erl6
3 files changed, 32 insertions, 20 deletions
diff --git a/src/gun.erl b/src/gun.erl
index 6251dc7..8a101a7 100644
--- a/src/gun.erl
+++ b/src/gun.erl
@@ -1698,29 +1698,41 @@ commands([TLSHandshake={tls_handshake, _, _, _}], State) ->
{next_event, internal, TLSHandshake}}.
disconnect(State0=#state{owner=Owner, status=Status, opts=Opts,
- socket=Socket, transport=Transport,
+ intermediaries=Intermediaries, socket=Socket, transport=Transport0,
protocol=Protocol, protocol_state=ProtoState,
event_handler=EvHandler, event_handler_state=EvHandlerState0}, Reason) ->
EvHandlerState1 = Protocol:close(Reason, ProtoState, EvHandler, EvHandlerState0),
- _ = Transport:close(Socket),
+ _ = Transport0:close(Socket),
EvHandlerState = EvHandler:disconnect(#{reason => Reason}, EvHandlerState1),
- State = State0#state{event_handler_state=EvHandlerState},
+ State1 = State0#state{event_handler_state=EvHandlerState},
case Status of
{down, DownReason} ->
- owner_down(DownReason, State);
+ owner_down(DownReason, State1);
shutdown ->
- {stop, shutdown, State};
+ {stop, shutdown, State1};
{up, _} ->
%% We closed the socket, discard any remaining socket events.
- disconnect_flush(State),
+ disconnect_flush(State1),
KilledStreams = Protocol:down(ProtoState),
Owner ! {gun_down, self(), Protocol:name(), Reason, KilledStreams},
Retry = maps:get(retry, Opts, 5),
- %% @todo We need to reset the origin_scheme/host/port and the transport
- %% as well as remove the intermediaries.
- {next_state, not_connected,
- keepalive_cancel(State#state{socket=undefined,
- protocol=undefined, protocol_state=undefined}),
+ State2 = keepalive_cancel(State1#state{
+ socket=undefined, protocol=undefined, protocol_state=undefined}),
+ State = case Intermediaries of
+ [] ->
+ State2;
+ _ ->
+ #{host := OriginHost, port := OriginPort,
+ transport := OriginTransport} = lists:last(Intermediaries),
+ {OriginScheme, Transport} = case OriginTransport of
+ tcp -> {<<"http">>, gun_tcp};
+ tls -> {<<"https">>, gun_tls}
+ end,
+ State2#state{transport=Transport, origin_scheme=OriginScheme,
+ origin_host=OriginHost, origin_port=OriginPort,
+ intermediaries=[]}
+ end,
+ {next_state, not_connected, State,
{next_event, internal, {retries, Retry, Reason}}}
end.
diff --git a/test/rfc7231_SUITE.erl b/test/rfc7231_SUITE.erl
index b779b48..05af83a 100644
--- a/test/rfc7231_SUITE.erl
+++ b/test/rfc7231_SUITE.erl
@@ -62,17 +62,17 @@ do_proxy_init(Parent, Transport, Status, ConnectRespHeaders, Delay) ->
Parent ! {self(), Port},
{ok, ClientSocket} = case Transport of
gun_tcp ->
- gen_tcp:accept(ListenSocket, 5000);
+ gen_tcp:accept(ListenSocket, infinity);
gun_tls ->
- {ok, ClientSocket0} = ssl:transport_accept(ListenSocket, 5000),
- ssl:ssl_accept(ClientSocket0, 5000),
+ {ok, ClientSocket0} = ssl:transport_accept(ListenSocket, infinity),
+ ssl:ssl_accept(ClientSocket0, infinity),
{ok, ClientSocket0}
end,
{ok, Data} = case Transport of
gun_tcp ->
- gen_tcp:recv(ClientSocket, 0, 1000);
+ gen_tcp:recv(ClientSocket, 0, infinity);
gun_tls ->
- ssl:recv(ClientSocket, 0, 1000)
+ ssl:recv(ClientSocket, 0, infinity)
end,
{Method= <<"CONNECT">>, Authority, Version, Rest} = cow_http:parse_request_line(Data),
{Headers, <<>>} = cow_http:parse_headers(Rest),
@@ -95,7 +95,7 @@ do_proxy_init(Parent, Transport, Status, ConnectRespHeaders, Delay) ->
inet:setopts(OriginSocket, [{active, true}]),
do_proxy_loop(Transport, ClientSocket, OriginSocket);
true ->
- timer:sleep(2000)
+ timer:sleep(infinity)
end.
do_proxy_loop(Transport, ClientSocket, OriginSocket) ->
diff --git a/test/rfc7540_SUITE.erl b/test/rfc7540_SUITE.erl
index 42d3cd3..56555c1 100644
--- a/test/rfc7540_SUITE.erl
+++ b/test/rfc7540_SUITE.erl
@@ -68,10 +68,10 @@ do_proxy_init(Proxy=#proxy{parent=Parent, transport=Transport}) ->
Parent ! {self(), Port},
{ok, Socket} = case Transport of
gun_tcp ->
- gen_tcp:accept(ListenSocket, 5000);
+ gen_tcp:accept(ListenSocket, infinity);
gun_tls ->
- {ok, Socket0} = ssl:transport_accept(ListenSocket, 5000),
- ssl:handshake(Socket0, 5000),
+ {ok, Socket0} = ssl:transport_accept(ListenSocket, infinity),
+ ssl:handshake(Socket0, infinity),
{ok, <<"h2">>} = ssl:negotiated_protocol(Socket0),
{ok, Socket0}
end,