@@ -10,7 +10,13 @@ pub use crate::errors::*;
1010#[ derive( Debug , Copy , Clone ) ]
1111pub enum Backend {
1212 Curl ,
13- Reqwest ,
13+ Reqwest ( TlsBackend ) ,
14+ }
15+
16+ #[ derive( Debug , Copy , Clone ) ]
17+ pub enum TlsBackend {
18+ Rustls ,
19+ Default ,
1420}
1521
1622#[ derive( Debug , Copy , Clone ) ]
@@ -30,7 +36,7 @@ fn download_with_backend(
3036) -> Result < ( ) > {
3137 match backend {
3238 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 ) ,
3440 }
3541}
3642
@@ -249,9 +255,10 @@ pub mod curl {
249255#[ cfg( feature = "reqwest-backend" ) ]
250256pub mod reqwest_be {
251257 use super :: Event ;
258+ use super :: TlsBackend ;
252259 use crate :: errors:: * ;
253260 use lazy_static:: lazy_static;
254- use reqwest:: blocking:: { Client , Response } ;
261+ use reqwest:: blocking:: { Client , ClientBuilder , Response } ;
255262 use reqwest:: { header, Proxy } ;
256263 use std:: io;
257264 use std:: time:: Duration ;
@@ -261,13 +268,15 @@ pub mod reqwest_be {
261268 url : & Url ,
262269 resume_from : u64 ,
263270 callback : & dyn Fn ( Event < ' _ > ) -> Result < ( ) > ,
271+ tls : TlsBackend ,
264272 ) -> Result < ( ) > {
265273 // Short-circuit reqwest for the "file:" URL scheme
266274 if download_from_file_url ( url, resume_from, callback) ? {
267275 return Ok ( ( ) ) ;
268276 }
269277
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" ) ?;
271280
272281 if !res. status ( ) . is_success ( ) {
273282 let code: u16 = res. status ( ) . into ( ) ;
@@ -295,13 +304,34 @@ pub mod reqwest_be {
295304 }
296305 }
297306
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" ) ]
298314 lazy_static ! {
299- static ref CLIENT : Client = {
315+ static ref CLIENT_RUSTLS_TLS : Client = {
300316 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( )
305335 . build( )
306336 } ;
307337
@@ -319,8 +349,22 @@ pub mod reqwest_be {
319349 env_proxy:: for_url ( url) . to_url ( )
320350 }
321351
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 ( ) ) ;
324368
325369 if resume_from != 0 {
326370 req = req. header ( header:: RANGE , format ! ( "bytes={}-" , resume_from) ) ;
0 commit comments