aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2019-09-16 21:26:51 +0200
committerLoïc Hoguin <[email protected]>2019-09-22 16:46:35 +0200
commit28c19230eda29c42b376e35046d39acc1365881a (patch)
treeae04380ad338eb6f6ffe577529d5f2ff7d888872
parent5043b98d5301e41238afd15d271f5c6b68081b04 (diff)
downloadgun-28c19230eda29c42b376e35046d39acc1365881a.tar.gz
gun-28c19230eda29c42b376e35046d39acc1365881a.tar.bz2
gun-28c19230eda29c42b376e35046d39acc1365881a.zip
Further consolidation of TLS handshakes
-rw-r--r--src/gun.erl25
-rw-r--r--src/gun_tls_proxy.erl7
2 files changed, 12 insertions, 20 deletions
diff --git a/src/gun.erl b/src/gun.erl
index cc1a2b2..85e9405 100644
--- a/src/gun.erl
+++ b/src/gun.erl
@@ -961,23 +961,23 @@ tls_handshake(internal, {tls_handshake, HandshakeEvent, Protocols},
commands({error, Reason}, State)
end;
%% TLS over TLS.
-%% @todo Protocols
tls_handshake(internal, {tls_handshake,
- HandshakeEvent0=#{tls_opts := TLSOpts, timeout := TLSTimeout}, _Protocols},
+ HandshakeEvent0=#{tls_opts := TLSOpts, timeout := TLSTimeout}, Protocols},
State=#state{socket=Socket, transport=gun_tls, origin_host=OriginHost, origin_port=OriginPort,
event_handler=EvHandler, event_handler_state=EvHandlerState0}) ->
HandshakeEvent = HandshakeEvent0#{socket => Socket},
EvHandlerState = EvHandler:tls_handshake_start(HandshakeEvent, EvHandlerState0),
{ok, ProxyPid} = gun_tls_proxy:start_link(OriginHost, OriginPort,
- TLSOpts, TLSTimeout, Socket, gun_tls, HandshakeEvent),
+ TLSOpts, TLSTimeout, Socket, gun_tls, {HandshakeEvent, Protocols}),
commands([{switch_transport, gun_tls_proxy, ProxyPid}], State#state{
socket=ProxyPid, transport=gun_tls_proxy, event_handler_state=EvHandlerState});
%% When using gun_tls_proxy we need a separate message to know whether
%% the handshake succeeded and whether we need to switch to a different protocol.
-tls_handshake(info, {gun_tls_proxy, Socket, {ok, NewProtocol}, HandshakeEvent},
+tls_handshake(info, {gun_tls_proxy, Socket, {ok, Negotiated}, {HandshakeEvent, Protocols}},
State0=#state{socket=Socket, transport=Transport,
protocol=CurrentProtocol, protocol_state=ProtoState0,
event_handler=EvHandler, event_handler_state=EvHandlerState0}) ->
+ NewProtocol = protocol_negotiated(Negotiated, Protocols),
EvHandlerState = EvHandler:tls_handshake_end(HandshakeEvent#{
socket => Socket,
protocol => NewProtocol:name()
@@ -993,7 +993,7 @@ tls_handshake(info, {gun_tls_proxy, Socket, {ok, NewProtocol}, HandshakeEvent},
commands([{switch_protocol, NewProtocol, ProtoState0}], State1)
end,
{next_state, connected, State};
-tls_handshake(info, {gun_tls_proxy, Socket, Error = {error, Reason}, HandshakeEvent},
+tls_handshake(info, {gun_tls_proxy, Socket, Error = {error, Reason}, {HandshakeEvent, _}},
State=#state{socket=Socket, event_handler=EvHandler, event_handler_state=EvHandlerState0}) ->
EvHandlerState = EvHandler:tls_handshake_end(HandshakeEvent#{
error => Reason
@@ -1008,15 +1008,7 @@ normal_tls_handshake(Socket, State=#state{event_handler=EvHandler, event_handler
EvHandlerState1 = EvHandler:tls_handshake_start(HandshakeEvent, EvHandlerState0),
case gun_tls:connect(Socket, TLSOpts, TLSTimeout) of
{ok, TLSSocket} ->
- Protocol = case ssl:negotiated_protocol(TLSSocket) of
- {ok, <<"h2">>} -> gun_http2;
- {ok, <<"http/1.1">>} -> gun_http;
- {error, protocol_not_negotiated} ->
- case Protocols of
- [{socks, _}] -> gun_socks;
- _ -> gun_http
- end
- end,
+ Protocol = protocol_negotiated(ssl:negotiated_protocol(TLSSocket), Protocols),
EvHandlerState = EvHandler:tls_handshake_end(HandshakeEvent#{
socket => TLSSocket,
protocol => Protocol:name()
@@ -1029,6 +1021,11 @@ normal_tls_handshake(Socket, State=#state{event_handler=EvHandler, event_handler
{error, Reason, State#state{event_handler_state=EvHandlerState}}
end.
+protocol_negotiated({ok, <<"h2">>}, _) -> gun_http2;
+protocol_negotiated({ok, <<"http/1.1">>}, _) -> gun_http;
+protocol_negotiated({error, protocol_not_negotiated}, [{socks, _}]) -> gun_socks;
+protocol_negotiated({error, protocol_not_negotiated}, _) -> gun_http.
+
not_fully_connected(Type, Event, State) ->
handle_common_connected(Type, Event, ?FUNCTION_NAME, State).
diff --git a/src/gun_tls_proxy.erl b/src/gun_tls_proxy.erl
index d519919..1bd56cb 100644
--- a/src/gun_tls_proxy.erl
+++ b/src/gun_tls_proxy.erl
@@ -237,12 +237,7 @@ not_connected(cast, Msg={setopts, _}, State) ->
{keep_state_and_data, postpone};
not_connected(cast, Msg={connect_proc, {ok, Socket}}, State=#state{owner_pid=OwnerPid, extra=Extra}) ->
?DEBUG_LOG("msg ~0p state ~0p", [Msg, State]),
- %% @todo We should distinguish case when no protocol was negotiated (for socks).
- Protocol = case ssl:negotiated_protocol(Socket) of
- {ok, <<"h2">>} -> gun_http2;
- _ -> gun_http
- end,
- OwnerPid ! {?MODULE, self(), {ok, Protocol}, Extra},
+ OwnerPid ! {?MODULE, self(), {ok, ssl:negotiated_protocol(Socket)}, Extra},
%% We need to spawn this call before OTP-21.2 because it triggers
%% a cb_setopts call that blocks us. Might be OK to just leave it
%% like this once we support 21.2+ only.