11#![ cfg( feature = "reqwest-backend" ) ]
22
33use std:: env:: { remove_var, set_var} ;
4+ use std:: error:: Error ;
5+ use std:: net:: TcpListener ;
6+ use std:: sync:: atomic:: { AtomicUsize , Ordering } ;
7+ use std:: sync:: Mutex ;
8+ use std:: thread;
9+ use std:: time:: Duration ;
410
511use env_proxy:: for_url;
12+ use lazy_static:: lazy_static;
13+ use reqwest:: { blocking:: Client , Proxy } ;
614use url:: Url ;
715
16+ lazy_static ! {
17+ static ref SERIALISE_TESTS : Mutex <( ) > = Mutex :: new( ( ) ) ;
18+ }
19+
820fn scrub_env ( ) {
921 remove_var ( "http_proxy" ) ;
1022 remove_var ( "https_proxy" ) ;
@@ -20,6 +32,9 @@ fn scrub_env() {
2032// Tests for correctly retrieving the proxy (host, port) tuple from $https_proxy
2133#[ test]
2234fn read_basic_proxy_params ( ) {
35+ let _guard = SERIALISE_TESTS
36+ . lock ( )
37+ . expect ( "Unable to lock the test guard" ) ;
2338 scrub_env ( ) ;
2439 set_var ( "https_proxy" , "http://proxy.example.com:8080" ) ;
2540 let u = Url :: parse ( "https://www.example.org" ) . ok ( ) . unwrap ( ) ;
@@ -28,3 +43,41 @@ fn read_basic_proxy_params() {
2843 Some ( ( "proxy.example.com" . to_string( ) , 8080 ) )
2944 ) ;
3045}
46+
47+ // Tests to verify if socks feature is available and being used
48+ #[ test]
49+ fn socks_proxy_request ( ) {
50+ static CALL_COUNT : AtomicUsize = AtomicUsize :: new ( 0 ) ;
51+ let _guard = SERIALISE_TESTS
52+ . lock ( )
53+ . expect ( "Unable to lock the test guard" ) ;
54+
55+ scrub_env ( ) ;
56+ set_var ( "all_proxy" , "socks5://127.0.0.1:1080" ) ;
57+
58+ thread:: spawn ( move || {
59+ let listener = TcpListener :: bind ( "127.0.0.1:1080" ) . unwrap ( ) ;
60+ let incoming = listener. incoming ( ) ;
61+ for _ in incoming {
62+ CALL_COUNT . fetch_add ( 1 , Ordering :: SeqCst ) ;
63+ }
64+ } ) ;
65+
66+ let env_proxy = |url : & Url | for_url ( & url) . to_url ( ) ;
67+ let url = Url :: parse ( "http://example.org" ) . unwrap ( ) ;
68+
69+ let client = Client :: builder ( )
70+ . proxy ( Proxy :: custom ( env_proxy) )
71+ . timeout ( Duration :: from_secs ( 1 ) )
72+ . build ( )
73+ . unwrap ( ) ;
74+ let res = client. get ( url. as_str ( ) ) . send ( ) ;
75+
76+ if let Err ( e) = res {
77+ let s = e. source ( ) . unwrap ( ) ;
78+ assert_eq ! ( CALL_COUNT . load( Ordering :: SeqCst ) , 1 ) ;
79+ assert ! ( s. to_string( ) . contains( "socks connect error" ) ) ;
80+ } else {
81+ panic ! ( "Socks proxy was ignored" )
82+ }
83+ }
0 commit comments