@@ -10,7 +10,13 @@ pub use crate::errors::*;
10
10
#[ derive( Debug , Copy , Clone ) ]
11
11
pub enum Backend {
12
12
Curl ,
13
- Reqwest ,
13
+ Reqwest ( TlsBackend ) ,
14
+ }
15
+
16
+ #[ derive( Debug , Copy , Clone ) ]
17
+ pub enum TlsBackend {
18
+ Rustls ,
19
+ Default ,
14
20
}
15
21
16
22
#[ derive( Debug , Copy , Clone ) ]
@@ -30,7 +36,7 @@ fn download_with_backend(
30
36
) -> Result < ( ) > {
31
37
match backend {
32
38
Backend :: Curl => curl:: download ( url, resume_from, callback) ,
33
- Backend :: Reqwest => reqwest_be:: download ( url, resume_from, callback) ,
39
+ Backend :: Reqwest ( tls ) => reqwest_be:: download ( url, resume_from, callback, tls ) ,
34
40
}
35
41
}
36
42
@@ -249,9 +255,10 @@ pub mod curl {
249
255
#[ cfg( feature = "reqwest-backend" ) ]
250
256
pub mod reqwest_be {
251
257
use super :: Event ;
258
+ use super :: TlsBackend ;
252
259
use crate :: errors:: * ;
253
260
use lazy_static:: lazy_static;
254
- use reqwest:: blocking:: { Client , Response } ;
261
+ use reqwest:: blocking:: { Client , ClientBuilder , Response } ;
255
262
use reqwest:: { header, Proxy } ;
256
263
use std:: io;
257
264
use std:: time:: Duration ;
@@ -261,13 +268,15 @@ pub mod reqwest_be {
261
268
url : & Url ,
262
269
resume_from : u64 ,
263
270
callback : & dyn Fn ( Event < ' _ > ) -> Result < ( ) > ,
271
+ tls : TlsBackend ,
264
272
) -> Result < ( ) > {
265
273
// Short-circuit reqwest for the "file:" URL scheme
266
274
if download_from_file_url ( url, resume_from, callback) ? {
267
275
return Ok ( ( ) ) ;
268
276
}
269
277
270
- let mut res = request ( url, resume_from) . chain_err ( || "failed to make network request" ) ?;
278
+ let mut res =
279
+ request ( url, resume_from, tls) . chain_err ( || "failed to make network request" ) ?;
271
280
272
281
if !res. status ( ) . is_success ( ) {
273
282
let code: u16 = res. status ( ) . into ( ) ;
@@ -295,13 +304,34 @@ pub mod reqwest_be {
295
304
}
296
305
}
297
306
307
+ fn client_generic ( ) -> ClientBuilder {
308
+ Client :: builder ( )
309
+ . gzip ( false )
310
+ . proxy ( Proxy :: custom ( env_proxy) )
311
+ . timeout ( Duration :: from_secs ( 30 ) )
312
+ }
313
+ #[ cfg( feature = "reqwest-rustls-tls" ) ]
298
314
lazy_static ! {
299
- static ref CLIENT : Client = {
315
+ static ref CLIENT_RUSTLS_TLS : Client = {
300
316
let catcher = || {
301
- Client :: builder( )
302
- . gzip( false )
303
- . proxy( Proxy :: custom( env_proxy) )
304
- . timeout( Duration :: from_secs( 30 ) )
317
+ client_generic( ) . use_rustls_tls( )
318
+ . build( )
319
+ } ;
320
+
321
+ // woah, an unwrap?!
322
+ // It's OK. This is the same as what is happening in curl.
323
+ //
324
+ // The curl::Easy::new() internally assert!s that the initialized
325
+ // Easy is not null. Inside reqwest, the errors here would be from
326
+ // the TLS library returning a null pointer as well.
327
+ catcher( ) . unwrap( )
328
+ } ;
329
+ }
330
+ #[ cfg( feature = "reqwest-default-tls" ) ]
331
+ lazy_static ! {
332
+ static ref CLIENT_DEFAULT_TLS : Client = {
333
+ let catcher = || {
334
+ client_generic( )
305
335
. build( )
306
336
} ;
307
337
@@ -319,8 +349,22 @@ pub mod reqwest_be {
319
349
env_proxy:: for_url ( url) . to_url ( )
320
350
}
321
351
322
- fn request ( url : & Url , resume_from : u64 ) -> reqwest:: Result < Response > {
323
- let mut req = CLIENT . get ( url. as_str ( ) ) ;
352
+ fn request ( url : & Url , resume_from : u64 , backend : TlsBackend ) -> reqwest:: Result < Response > {
353
+ let client: & Client = match backend {
354
+ #[ cfg( feature = "reqwest-rustls-tls" ) ]
355
+ TlsBackend :: Rustls => & CLIENT_RUSTLS_TLS ,
356
+ #[ cfg( not( feature = "reqwest-rustls-tls" ) ) ]
357
+ TlsBackend :: Default => {
358
+ return Err ( ErrorKind :: BackendUnavailable ( "reqwest rustls" ) . into ( ) ) ;
359
+ }
360
+ #[ cfg( feature = "reqwest-default-tls" ) ]
361
+ TlsBackend :: Default => & CLIENT_DEFAULT_TLS ,
362
+ #[ cfg( not( feature = "reqwest-default-tls" ) ) ]
363
+ TlsBackend :: Default => {
364
+ return Err ( ErrorKind :: BackendUnavailable ( "reqwest default TLS" ) . into ( ) ) ;
365
+ }
366
+ } ;
367
+ let mut req = client. get ( url. as_str ( ) ) ;
324
368
325
369
if resume_from != 0 {
326
370
req = req. header ( header:: RANGE , format ! ( "bytes={}-" , resume_from) ) ;
0 commit comments