1
1
use std:: convert:: Infallible ;
2
+ use std:: env:: remove_var;
2
3
use std:: fs;
3
4
use std:: io;
4
5
use std:: net:: SocketAddr ;
5
6
use std:: path:: Path ;
7
+ use std:: sync:: LazyLock ;
6
8
use std:: sync:: mpsc:: { Sender , channel} ;
7
9
use std:: thread;
8
10
@@ -20,7 +22,7 @@ mod curl {
20
22
21
23
use url:: Url ;
22
24
23
- use super :: { serve_file, tmp_dir, write_file} ;
25
+ use super :: { scrub_env , serve_file, tmp_dir, write_file} ;
24
26
use crate :: download:: { Backend , Event } ;
25
27
26
28
#[ tokio:: test]
@@ -43,6 +45,7 @@ mod curl {
43
45
44
46
#[ tokio:: test]
45
47
async fn callback_gets_all_data_as_if_the_download_happened_all_at_once ( ) {
48
+ let _guard = scrub_env ( ) . await ;
46
49
let tmpdir = tmp_dir ( ) ;
47
50
let target_path = tmpdir. path ( ) . join ( "downloaded" ) ;
48
51
write_file ( & target_path, "123" ) ;
@@ -94,46 +97,28 @@ mod curl {
94
97
95
98
#[ cfg( any( feature = "reqwest-rustls-tls" , feature = "reqwest-native-tls" ) ) ]
96
99
mod reqwest {
97
- use std:: env:: { remove_var , set_var} ;
100
+ use std:: env:: set_var;
98
101
use std:: error:: Error ;
99
102
use std:: net:: TcpListener ;
103
+ use std:: sync:: Mutex ;
100
104
use std:: sync:: atomic:: { AtomicBool , AtomicUsize , Ordering } ;
101
- use std:: sync:: { LazyLock , Mutex } ;
102
105
use std:: thread;
103
106
use std:: time:: Duration ;
104
107
105
108
use env_proxy:: for_url;
106
109
use reqwest:: { Client , Proxy } ;
107
110
use url:: Url ;
108
111
109
- use super :: { serve_file, tmp_dir, write_file} ;
112
+ use super :: { scrub_env , serve_file, tmp_dir, write_file} ;
110
113
use crate :: download:: { Backend , Event , TlsBackend } ;
111
114
112
- static SERIALISE_TESTS : LazyLock < tokio:: sync:: Mutex < ( ) > > =
113
- LazyLock :: new ( || tokio:: sync:: Mutex :: new ( ( ) ) ) ;
114
-
115
- unsafe fn scrub_env ( ) {
116
- unsafe {
117
- remove_var ( "http_proxy" ) ;
118
- remove_var ( "https_proxy" ) ;
119
- remove_var ( "HTTPS_PROXY" ) ;
120
- remove_var ( "ftp_proxy" ) ;
121
- remove_var ( "FTP_PROXY" ) ;
122
- remove_var ( "all_proxy" ) ;
123
- remove_var ( "ALL_PROXY" ) ;
124
- remove_var ( "no_proxy" ) ;
125
- remove_var ( "NO_PROXY" ) ;
126
- }
127
- }
128
-
129
115
// Tests for correctly retrieving the proxy (host, port) tuple from $https_proxy
130
116
#[ tokio:: test]
131
117
async fn read_basic_proxy_params ( ) {
132
- let _guard = SERIALISE_TESTS . lock ( ) . await ;
118
+ let _guard = scrub_env ( ) . await ;
133
119
// SAFETY: We are setting environment variables when `SERIALISE_TESTS` is locked,
134
120
// and those environment variables in question are not relevant elsewhere in the test suite.
135
121
unsafe {
136
- scrub_env ( ) ;
137
122
set_var ( "https_proxy" , "http://proxy.example.com:8080" ) ;
138
123
}
139
124
let u = Url :: parse ( "https://www.example.org" ) . ok ( ) . unwrap ( ) ;
@@ -147,12 +132,11 @@ mod reqwest {
147
132
#[ tokio:: test]
148
133
async fn socks_proxy_request ( ) {
149
134
static CALL_COUNT : AtomicUsize = AtomicUsize :: new ( 0 ) ;
150
- let _guard = SERIALISE_TESTS . lock ( ) . await ;
135
+ let _guard = scrub_env ( ) . await ;
151
136
152
137
// SAFETY: We are setting environment variables when `SERIALISE_TESTS` is locked,
153
138
// and those environment variables in question are not relevant elsewhere in the test suite.
154
139
unsafe {
155
- scrub_env ( ) ;
156
140
set_var ( "all_proxy" , "socks5://127.0.0.1:1080" ) ;
157
141
}
158
142
@@ -210,6 +194,7 @@ mod reqwest {
210
194
211
195
#[ tokio:: test]
212
196
async fn callback_gets_all_data_as_if_the_download_happened_all_at_once ( ) {
197
+ let _guard = scrub_env ( ) . await ;
213
198
let tmpdir = tmp_dir ( ) ;
214
199
let target_path = tmpdir. path ( ) . join ( "downloaded" ) ;
215
200
write_file ( & target_path, "123" ) ;
@@ -363,3 +348,31 @@ fn serve_contents(
363
348
}
364
349
res
365
350
}
351
+
352
+ /// Clear proxy-related environment variables
353
+ ///
354
+ /// Every test using a proxy-sensitive URL should call this and hold the returned guard,
355
+ /// regardless of whether the test is going to set its own proxy environment variables.
356
+ async fn scrub_env ( ) -> tokio:: sync:: MutexGuard < ' static , ( ) > {
357
+ static SERIALISE_TESTS : LazyLock < tokio:: sync:: Mutex < ( ) > > =
358
+ LazyLock :: new ( || tokio:: sync:: Mutex :: new ( ( ) ) ) ;
359
+
360
+ let guard = SERIALISE_TESTS . lock ( ) . await ;
361
+
362
+ // SAFETY: We are clearing environment variables when `SERIALISE_TESTS` is locked, and those
363
+ // environment variables in question are only relevant in tests that continue to hold this
364
+ // mutex guard.
365
+ unsafe {
366
+ remove_var ( "http_proxy" ) ;
367
+ remove_var ( "https_proxy" ) ;
368
+ remove_var ( "HTTPS_PROXY" ) ;
369
+ remove_var ( "ftp_proxy" ) ;
370
+ remove_var ( "FTP_PROXY" ) ;
371
+ remove_var ( "all_proxy" ) ;
372
+ remove_var ( "ALL_PROXY" ) ;
373
+ remove_var ( "no_proxy" ) ;
374
+ remove_var ( "NO_PROXY" ) ;
375
+ }
376
+
377
+ guard
378
+ }
0 commit comments