diff options
author | Loïc Hoguin <[email protected]> | 2020-08-24 17:06:23 +0200 |
---|---|---|
committer | Loïc Hoguin <[email protected]> | 2020-09-21 15:51:57 +0200 |
commit | d056e5fb2a1fbb54e108c5c61384573acf21b4cf (patch) | |
tree | ccf9131d63fbace32e2d99941fb6b1d788f6ec7f /src/gun.erl | |
parent | 2c8db0879109dd90443d7b276e5ca2daf83920bc (diff) | |
download | gun-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.erl | 37 |
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, |