aboutsummaryrefslogtreecommitdiffstats
path: root/src/gun.erl
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2020-08-24 17:06:23 +0200
committerLoïc Hoguin <[email protected]>2020-09-21 15:51:57 +0200
commitd056e5fb2a1fbb54e108c5c61384573acf21b4cf (patch)
treeccf9131d63fbace32e2d99941fb6b1d788f6ec7f /src/gun.erl
parent2c8db0879109dd90443d7b276e5ca2daf83920bc (diff)
downloadgun-d056e5fb2a1fbb54e108c5c61384573acf21b4cf.tar.gz
gun-d056e5fb2a1fbb54e108c5c61384573acf21b4cf.tar.bz2
gun-d056e5fb2a1fbb54e108c5c61384573acf21b4cf.zip
Replace gun_tunnel_up/3 message with /4 variant
Also fixes all the tests. Lots of work remain around protocols (how best to pass the base stream_ref to them? maybe the current solution, maybe a new argument to Protocol:init) and strengthen the concept of stream_ref, at least with its own type.
Diffstat (limited to 'src/gun.erl')
-rw-r--r--src/gun.erl37
1 files changed, 24 insertions, 13 deletions
diff --git a/src/gun.erl b/src/gun.erl
index 2f92b95..38c479e 100644
--- a/src/gun.erl
+++ b/src/gun.erl
@@ -668,10 +668,10 @@ connect(ServerPid, Destination, Headers) ->
-spec connect(pid(), connect_destination(), req_headers(), req_opts()) -> reference().
connect(ServerPid, Destination, Headers, ReqOpts) ->
- StreamRef = make_ref(),
+ Tunnel = get_tunnel(ReqOpts),
+ StreamRef = make_stream_ref(Tunnel),
InitialFlow = maps:get(flow, ReqOpts, infinity),
ReplyTo = maps:get(reply_to, ReqOpts, self()),
- %% @todo tunnel
gen_statem:cast(ServerPid, {connect, ReplyTo, StreamRef,
Destination, Headers, InitialFlow}),
StreamRef.
@@ -808,8 +808,6 @@ await_up(ServerPid, Timeout, MRef) ->
receive
{gun_up, ServerPid, Protocol} ->
{ok, Protocol};
- {gun_tunnel_up, ServerPid, Protocol} ->
- {ok, Protocol};
{'DOWN', MRef, process, ServerPid, Reason} ->
{error, {down, Reason}}
after Timeout ->
@@ -1092,8 +1090,17 @@ ensure_alpn_sni(Protocols0, TransOpts0, OriginHost) ->
%% Normal TLS handshake.
tls_handshake(internal, {tls_handshake, HandshakeEvent, Protocols, ReplyTo},
State0=#state{socket=Socket, transport=gun_tcp}) ->
+ StreamRef = maps:get(stream_ref, HandshakeEvent, undefined),
case normal_tls_handshake(Socket, State0, HandshakeEvent, Protocols) of
- {ok, TLSSocket, NewProtocol, State} ->
+ {ok, TLSSocket, NewProtocol0, State} ->
+ NewProtocol = {Protocol0, _} = case {StreamRef, NewProtocol0} of
+ {undefined, {_, _}} -> NewProtocol0;
+ {undefined, P} -> {P, #{}};
+ {_, {P, POpts}} -> {P, POpts#{stream_ref => StreamRef}};
+ {_, P} -> {P, #{stream_ref => StreamRef}}
+ end,
+ Protocol = gun:protocol_handler(Protocol0),
+ ReplyTo ! {gun_tunnel_up, self(), StreamRef, Protocol:name()},
commands([
{switch_transport, gun_tls, TLSSocket},
{switch_protocol, NewProtocol, ReplyTo}
@@ -1120,10 +1127,19 @@ tls_handshake(internal, {tls_handshake,
%% the handshake succeeded and whether we need to switch to a different protocol.
tls_handshake(info, {gun_tls_proxy, Socket, {ok, Negotiated}, {HandshakeEvent, Protocols, ReplyTo}},
State0=#state{socket=Socket, event_handler=EvHandler, event_handler_state=EvHandlerState0}) ->
- NewProtocol = protocol_negotiated(Negotiated, Protocols),
+ NewProtocol0 = protocol_negotiated(Negotiated, Protocols),
+ StreamRef = maps:get(stream_ref, HandshakeEvent, undefined),
+ NewProtocol = {Protocol0, _} = case {StreamRef, NewProtocol0} of
+ {undefined, {_, _}} -> NewProtocol0;
+ {undefined, P} -> {P, #{}};
+ {_, {P, POpts}} -> {P, POpts#{stream_ref => StreamRef}};
+ {_, P} -> {P, #{stream_ref => StreamRef}}
+ end,
+ Protocol = gun:protocol_handler(Protocol0),
+ ReplyTo ! {gun_tunnel_up, self(), StreamRef, Protocol:name()},
EvHandlerState = EvHandler:tls_handshake_end(HandshakeEvent#{
socket => Socket,
- protocol => NewProtocol
+ protocol => Protocol:name()
}, EvHandlerState0),
commands([{switch_protocol, NewProtocol, ReplyTo}], State0#state{event_handler_state=EvHandlerState});
tls_handshake(info, {gun_tls_proxy, Socket, Error = {error, Reason}, {HandshakeEvent, _, _}},
@@ -1578,7 +1594,7 @@ commands([{switch_transport, Transport, Socket}|Tail], State=#state{
messages=Transport:messages(), protocol_state=ProtoState,
event_handler_state=EvHandlerState}));
commands([{switch_protocol, Protocol0, ReplyTo}], State0=#state{
- opts=Opts, socket=Socket, transport=Transport, protocol=CurrentProtocol,
+ opts=Opts, socket=Socket, transport=Transport,
event_handler=EvHandler, event_handler_state=EvHandlerState0}) ->
{Protocol, ProtoOpts} = case Protocol0 of
{P, PO} -> {protocol_handler(P), PO};
@@ -1586,11 +1602,6 @@ commands([{switch_protocol, Protocol0, ReplyTo}], State0=#state{
Protocol1 = protocol_handler(P),
{Protocol1, maps:get(Protocol1:opts_name(), Opts, #{})}
end,
- %% When we switch_protocol from socks we must send a gun_tunnel_up message.
- _ = case CurrentProtocol of
- gun_socks -> ReplyTo ! {gun_tunnel_up, self(), Protocol:name()};
- _ -> ok
- end,
{StateName, ProtoState} = Protocol:init(ReplyTo, Socket, Transport, ProtoOpts),
EvHandlerState = EvHandler:protocol_changed(#{protocol => Protocol:name()}, EvHandlerState0),
%% We cancel the existing keepalive and, depending on the protocol,