diff options
author | Loïc Hoguin <[email protected]> | 2018-09-26 12:08:11 +0200 |
---|---|---|
committer | Loïc Hoguin <[email protected]> | 2018-09-26 12:08:11 +0200 |
commit | f328916937c67b3c9679e4f11d4594c39d36f85d (patch) | |
tree | 53c8c3df47443227fc2800ffe450c94ab7e58478 /src/gun.erl | |
parent | baf0e420917ca1cb2806f8594a6cdb4710d2793d (diff) | |
download | gun-f328916937c67b3c9679e4f11d4594c39d36f85d.tar.gz gun-f328916937c67b3c9679e4f11d4594c39d36f85d.tar.bz2 gun-f328916937c67b3c9679e4f11d4594c39d36f85d.zip |
Keep track of the intermediaries the connection go through
Also augment the CONNECT tests to confirm that the
intermediaries are accounted for.
Diffstat (limited to 'src/gun.erl')
-rw-r--r-- | src/gun.erl | 48 |
1 files changed, 44 insertions, 4 deletions
diff --git a/src/gun.erl b/src/gun.erl index 9c92281..daa5c62 100644 --- a/src/gun.erl +++ b/src/gun.erl @@ -128,6 +128,14 @@ }. -export_type([connect_destination/0]). +-type intermediary() :: #{ + type := connect, + host := inet:hostname() | inet:ip_address(), + port := inet:port_number(), + transport := tcp | tls, + protocol := http | http2 +}. + %% @todo When/if HTTP/2 CONNECT gets implemented, we will want an option here %% to indicate that the request must be sent on an existing CONNECT stream. %% This is of course not required for HTTP/1.1 since the CONNECT takes over @@ -163,6 +171,7 @@ port :: inet:port_number(), origin_host :: inet:hostname() | inet:ip_address(), origin_port :: inet:port_number(), + intermediaries = [] :: [intermediary()], opts :: opts(), keepalive_ref :: undefined | reference(), socket :: undefined | inet:socket() | ssl:sslsocket(), @@ -275,9 +284,25 @@ consider_tracing(_, _) -> -spec info(pid()) -> map(). info(ServerPid) -> - {_, #state{socket=Socket, transport=Transport}} = sys:get_state(ServerPid), + {_, #state{ + socket=Socket, + transport=Transport, + protocol=Protocol, + origin_host=OriginHost, + origin_port=OriginPort, + intermediaries=Intermediaries + }} = sys:get_state(ServerPid), {ok, {SockIP, SockPort}} = Transport:sockname(Socket), - #{sock_ip => SockIP, sock_port => SockPort}. + #{ + transport => Transport:name(), + protocol => Protocol:name(), + sock_ip => SockIP, + sock_port => SockPort, + origin_host => OriginHost, + origin_port => OriginPort, + %% Intermediaries are listed in the order data goes through them. + intermediaries => lists:reverse(Intermediaries) + }. -spec close(pid()) -> ok. close(ServerPid) -> @@ -866,8 +891,23 @@ commands([Error={error, _}|_], State=#state{socket=Socket, transport=Transport}) commands([{state, ProtoState}|Tail], State) -> commands(Tail, State#state{protocol_state=ProtoState}); %% @todo The scheme should probably not be ignored. -commands([{origin, _Scheme, Host, Port}|Tail], State) -> - commands(Tail, State#state{origin_host=Host, origin_port=Port}); +%% +%% Order is important: the origin must be changed before +%% the transport and/or protocol in order to keep track +%% of the intermediaries properly. +commands([{origin, _Scheme, Host, Port, Type}|Tail], + State=#state{transport=Transport, protocol=Protocol, + origin_host=IntermediateHost, origin_port=IntermediatePort, + intermediaries=Intermediaries}) -> + Info = #{ + type => Type, + host => IntermediateHost, + port => IntermediatePort, + transport => Transport:name(), + protocol => Protocol:name() + }, + commands(Tail, State#state{origin_host=Host, origin_port=Port, + intermediaries=[Info|Intermediaries]}); commands([{switch_transport, Transport, Socket}|Tail], State) -> commands(Tail, State#state{socket=Socket, transport=Transport}); %% @todo The two loops should be reunified and this clause generalized. |