From d7a561c3743dc7391566d3e0d28d8cf910080786 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Thu, 12 Nov 2020 17:17:32 +0100 Subject: 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. --- src/gun.erl | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) (limited to 'src/gun.erl') 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. -- cgit v1.2.3