aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2019-07-25 14:14:34 +0200
committerLoïc Hoguin <[email protected]>2019-07-25 14:14:34 +0200
commitc2ba2258a0020d82faa3e79162f05fc67d61b53e (patch)
treec812564c3896e1c2489b8c70bff0adc9d68e2867 /src
parent293ca3d58f64cd716e8b1f84330c29f229d5a4f2 (diff)
downloadgun-c2ba2258a0020d82faa3e79162f05fc67d61b53e.tar.gz
gun-c2ba2258a0020d82faa3e79162f05fc67d61b53e.tar.bz2
gun-c2ba2258a0020d82faa3e79162f05fc67d61b53e.zip
Add tls_handshake events for CONNECT through TCP proxies
Diffstat (limited to 'src')
-rw-r--r--src/gun_event.erl12
-rw-r--r--src/gun_http.erl37
2 files changed, 40 insertions, 9 deletions
diff --git a/src/gun_event.erl b/src/gun_event.erl
index c87af58..ed50fd7 100644
--- a/src/gun_event.erl
+++ b/src/gun_event.erl
@@ -55,8 +55,20 @@
-callback connect_end(connect_event(), State) -> State.
%% tls_handshake_start/tls_handshake_end.
+%%
+%% These events occur when connecting to a TLS server or when
+%% upgrading the connection to use TLS, for example using CONNECT.
+%% The stream_ref/reply_to values are only present when the TLS
+%% handshake occurs as a result of a request.
+%%
+%% @todo The current implementation of TLS over TLS will not result
+%% in an event being triggered when the TLS handshake fails. Instead
+%% the Gun process will exit because of the link to the gun_tls_proxy
+%% process.
-type tls_handshake_event() :: #{
+ stream_ref => reference(),
+ reply_to => pid(),
socket := inet:socket() | ssl:sslsocket(), %% The socket before/after will be different.
tls_opts := [ssl:connect_option()],
timeout := timeout(),
diff --git a/src/gun_http.erl b/src/gun_http.erl
index 08a287c..113de0d 100644
--- a/src/gun_http.erl
+++ b/src/gun_http.erl
@@ -274,8 +274,8 @@ handle_head(Data, State=#http_state{socket=Socket, transport=Transport,
ok
end,
%% @todo Figure out whether the event should trigger if the stream was cancelled.
- EvHandlerState = EvHandler:response_headers(#{
- stream_ref => StreamRef,
+ EvHandlerState1 = EvHandler:response_headers(#{
+ stream_ref => RealStreamRef,
reply_to => ReplyTo,
status => Status,
headers => Headers
@@ -296,33 +296,52 @@ handle_head(Data, State=#http_state{socket=Socket, transport=Transport,
%% and handled by the gun module directly.
{[{state, State2#http_state{socket=ProxyPid, transport=gun_tls_proxy}},
{origin, <<"https">>, NewHost, NewPort, connect},
- {switch_transport, gun_tls_proxy, ProxyPid}], EvHandlerState};
+ {switch_transport, gun_tls_proxy, ProxyPid}], EvHandlerState1};
#{transport := tls} ->
TLSOpts = maps:get(tls_opts, Destination, []),
TLSTimeout = maps:get(tls_handshake_timeout, Destination, infinity),
+ HandshakeEvent = #{
+ stream_ref => RealStreamRef,
+ reply_to => ReplyTo,
+ socket => Socket,
+ tls_opts => TLSOpts,
+ timeout => TLSTimeout
+ },
+ EvHandlerState2 = EvHandler:tls_handshake_start(HandshakeEvent, EvHandlerState1),
case gun_tls:connect(Socket, TLSOpts, TLSTimeout) of
{ok, TLSSocket} ->
- case ssl:negotiated_protocol(TLSSocket) of
- {ok, <<"h2">>} ->
+ Protocol = case ssl:negotiated_protocol(TLSSocket) of
+ {ok, <<"h2">>} -> gun_http2;
+ _ -> gun_http
+ end,
+ EvHandlerState = EvHandler:tls_handshake_end(HandshakeEvent#{
+ socket => TLSSocket,
+ protocol => Protocol:name()
+ }, EvHandlerState2),
+ case Protocol of
+ gun_http2 ->
{[{origin, <<"https">>, NewHost, NewPort, connect},
{switch_transport, gun_tls, TLSSocket},
{switch_protocol, gun_http2, State2}], EvHandlerState};
- _ ->
+ gun_http ->
{[{state, State2#http_state{socket=TLSSocket, transport=gun_tls}},
{origin, <<"https">>, NewHost, NewPort, connect},
{switch_transport, gun_tls, TLSSocket}], EvHandlerState}
end;
- Error ->
+ Error = {error, Reason} ->
+ EvHandlerState = EvHandler:tls_handshake_end(HandshakeEvent#{
+ error => Reason
+ }, EvHandlerState2),
{Error, EvHandlerState}
end;
_ ->
case maps:get(protocols, Destination, [http]) of
[http] ->
{[{state, State2},
- {origin, <<"http">>, NewHost, NewPort, connect}], EvHandlerState};
+ {origin, <<"http">>, NewHost, NewPort, connect}], EvHandlerState1};
[http2] ->
{[{origin, <<"http">>, NewHost, NewPort, connect},
- {switch_protocol, gun_http2, State2}], EvHandlerState}
+ {switch_protocol, gun_http2, State2}], EvHandlerState1}
end
end;
{_, _} when Status >= 100, Status =< 199 ->