@@ -10,6 +10,8 @@ use fs_err::File;
10
10
use multipart:: client:: lazy:: Multipart ;
11
11
use regex:: Regex ;
12
12
use std:: env;
13
+ #[ cfg( any( feature = "native-tls" , feature = "rustls" ) ) ]
14
+ use std:: ffi:: OsString ;
13
15
use std:: io;
14
16
use std:: path:: { Path , PathBuf } ;
15
17
use thiserror:: Error ;
@@ -84,7 +86,7 @@ pub enum UploadError {
84
86
/// TLS error
85
87
#[ cfg( feature = "native-tls" ) ]
86
88
#[ error( "TLS Error" ) ]
87
- TlsError ( #[ source] native_tls_crate :: Error ) ,
89
+ TlsError ( #[ source] native_tls :: Error ) ,
88
90
}
89
91
90
92
impl From < io:: Error > for UploadError {
@@ -100,8 +102,8 @@ impl From<ureq::Error> for UploadError {
100
102
}
101
103
102
104
#[ cfg( feature = "native-tls" ) ]
103
- impl From < native_tls_crate :: Error > for UploadError {
104
- fn from ( error : native_tls_crate :: Error ) -> Self {
105
+ impl From < native_tls :: Error > for UploadError {
106
+ fn from ( error : native_tls :: Error ) -> Self {
105
107
UploadError :: TlsError ( error)
106
108
}
107
109
}
@@ -269,21 +271,61 @@ fn http_proxy() -> Result<String, env::VarError> {
269
271
. or_else ( |_| env:: var ( "http_proxy" ) )
270
272
}
271
273
272
- #[ cfg( feature = "native-tls" ) ]
274
+ #[ cfg( any( feature = "native-tls" , feature = "rustls" ) ) ]
275
+ fn tls_ca_bundle ( ) -> Option < OsString > {
276
+ env:: var_os ( "MATURIN_CA_BUNDLE" )
277
+ . or_else ( || env:: var_os ( "REQUESTS_CA_BUNDLE" ) )
278
+ . or_else ( || env:: var_os ( "CURL_CA_BUNDLE" ) )
279
+ }
280
+
281
+ // Prefer rustls if both native-tls and rustls features are enabled
282
+ #[ cfg( all( feature = "native-tls" , not( feature = "rustls" ) ) ) ]
273
283
#[ allow( clippy:: result_large_err) ]
274
284
fn http_agent ( ) -> Result < ureq:: Agent , UploadError > {
275
285
use std:: sync:: Arc ;
276
286
277
- let mut builder =
278
- ureq:: builder ( ) . tls_connector ( Arc :: new ( native_tls_crate:: TlsConnector :: new ( ) ?) ) ;
287
+ let mut builder = ureq:: builder ( ) ;
279
288
if let Ok ( proxy) = http_proxy ( ) {
280
289
let proxy = ureq:: Proxy :: new ( proxy) ?;
281
290
builder = builder. proxy ( proxy) ;
282
291
} ;
292
+ let mut tls_builder = native_tls:: TlsConnector :: builder ( ) ;
293
+ if let Some ( ca_bundle) = tls_ca_bundle ( ) {
294
+ let mut reader = io:: BufReader :: new ( File :: open ( ca_bundle) ?) ;
295
+ for cert in rustls_pemfile:: certs ( & mut reader) ? {
296
+ tls_builder. add_root_certificate ( native_tls:: Certificate :: from_pem ( & cert) ?) ;
297
+ }
298
+ }
299
+ builder = builder. tls_connector ( Arc :: new ( tls_builder. build ( ) ?) ) ;
283
300
Ok ( builder. build ( ) )
284
301
}
285
302
286
- #[ cfg( not( feature = "native-tls" ) ) ]
303
+ #[ cfg( feature = "rustls" ) ]
304
+ #[ allow( clippy:: result_large_err) ]
305
+ fn http_agent ( ) -> Result < ureq:: Agent , UploadError > {
306
+ use std:: sync:: Arc ;
307
+
308
+ let mut builder = ureq:: builder ( ) ;
309
+ if let Ok ( proxy) = http_proxy ( ) {
310
+ let proxy = ureq:: Proxy :: new ( proxy) ?;
311
+ builder = builder. proxy ( proxy) ;
312
+ } ;
313
+ if let Some ( ca_bundle) = tls_ca_bundle ( ) {
314
+ let mut reader = io:: BufReader :: new ( File :: open ( ca_bundle) ?) ;
315
+ let certs = rustls_pemfile:: certs ( & mut reader) ?;
316
+ let mut root_certs = rustls:: RootCertStore :: empty ( ) ;
317
+ root_certs. add_parsable_certificates ( & certs) ;
318
+ let client_config = rustls:: ClientConfig :: builder ( )
319
+ . with_safe_defaults ( )
320
+ . with_root_certificates ( root_certs)
321
+ . with_no_client_auth ( ) ;
322
+ Ok ( builder. tls_config ( Arc :: new ( client_config) ) . build ( ) )
323
+ } else {
324
+ Ok ( builder. build ( ) )
325
+ }
326
+ }
327
+
328
+ #[ cfg( not( any( feature = "native-tls" , feature = "rustls" ) ) ) ]
287
329
#[ allow( clippy:: result_large_err) ]
288
330
fn http_agent ( ) -> Result < ureq:: Agent , UploadError > {
289
331
let mut builder = ureq:: builder ( ) ;
0 commit comments