From f75a5416c4979ca26b1fbb8a737def8d01a20c8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Fri, 20 Sep 2019 12:19:33 +0200 Subject: Supports going through multiple Socks proxies This commit also reworks the switch_protocol command. The `P | {P, Opts}` type is used here as well. This allows us to remove the code specific to Websocket. In addition a few new protocol functions allow us to declare what's the name of the options key for the protocol and what the capabilities are with regard to keepalive. --- test/socks_SUITE.erl | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) (limited to 'test') diff --git a/test/socks_SUITE.erl b/test/socks_SUITE.erl index 9d80328..e565017 100644 --- a/test/socks_SUITE.erl +++ b/test/socks_SUITE.erl @@ -257,3 +257,57 @@ do_socks5(OriginScheme, OriginTransport, OriginProtocol, ProxyTransport, SocksAu protocol := socks }]} = gun:info(ConnPid), gun:close(ConnPid). + +socks5_through_multiple_proxies(_) -> + doc("Gun can be used to establish a TCP connection " + "to an HTTP/1.1 server via a tunnel going through " + "two separate Socks5 proxies."), + {ok, OriginPid, OriginPort} = init_origin(tcp, http), + {ok, Proxy1Pid, Proxy1Port} = do_proxy_start(tcp, none), + {ok, Proxy2Pid, Proxy2Port} = do_proxy_start(tcp, none), + Authority = iolist_to_binary(["localhost:", integer_to_binary(OriginPort)]), + {ok, ConnPid} = gun:open("localhost", Proxy1Port, #{ + protocols => [{socks, #{ + host => "localhost", + port => Proxy2Port, + protocols => [{socks, #{ + host => "localhost", + port => OriginPort + }}] + }}] + }), + %% We receive a gun_up and two gun_socks_connected. + {ok, socks} = gun:await_up(ConnPid), + {ok, socks} = gun:await_up(ConnPid), + {ok, http} = gun:await_up(ConnPid), + %% The first proxy received two packets. + {auth_methods, 1, [none]} = receive_from(Proxy1Pid), + {connect, <<"localhost">>, Proxy2Port} = receive_from(Proxy1Pid), + %% So did the second proxy. + {auth_methods, 1, [none]} = receive_from(Proxy2Pid), + {connect, <<"localhost">>, OriginPort} = receive_from(Proxy2Pid), + handshake_completed = receive_from(OriginPid), + _ = gun:get(ConnPid, "/proxied"), + Data = receive_from(OriginPid), + Lines = binary:split(Data, <<"\r\n">>, [global]), + [<<"host: ", Authority/bits>>] = [L || <<"host: ", _/bits>> = L <- Lines], + #{ + transport := tcp, + protocol := http, + origin_scheme := <<"http">>, + origin_host := "localhost", + origin_port := OriginPort, + intermediaries := [#{ + type := socks5, + host := "localhost", + port := Proxy1Port, + transport := tcp, + protocol := socks + }, #{ + type := socks5, + host := "localhost", + port := Proxy2Port, + transport := tcp, + protocol := socks + }]} = gun:info(ConnPid), + gun:close(ConnPid). -- cgit v1.2.3