Skip to content

Commit c063ff9

Browse files
committed
Re-add rustls support and enable it by default
rustls is seen as mature enough for curl to depend on it optionally, and it recently has had an audit. This commit adds back rustls support removed by 86bb185 and enables it by default. You can opt out of rustls use by setting the RUSTUP_AVOID_RUSTLS env variable.
1 parent 4b9c9bb commit c063ff9

File tree

6 files changed

+203
-27
lines changed

6 files changed

+203
-27
lines changed

Cargo.lock

Lines changed: 112 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,14 @@ version = "1.22.1"
1313

1414
[features]
1515
curl-backend = ["download/curl-backend"]
16-
default = ["curl-backend", "reqwest-backend"]
16+
default = ["curl-backend", "reqwest-backend", "reqwest-default-tls", "reqwest-rustls-tls"]
17+
1718
reqwest-backend = ["download/reqwest-backend"]
1819
vendored-openssl = ['openssl/vendored']
20+
21+
reqwest-default-tls = ["download/reqwest-default-tls"]
22+
reqwest-rustls-tls = ["download/reqwest-rustls-tls"]
23+
1924
# Include in the default set to disable self-update and uninstall.
2025
no-self-update = []
2126

@@ -25,7 +30,7 @@ anyhow = "1.0.31"
2530
cfg-if = "1.0"
2631
chrono = "0.4"
2732
clap = "2"
28-
download = {path = "download"}
33+
download = { path = "download", default-features = false }
2934
effective-limits = "0.5.2"
3035
error-chain = "0.12"
3136
flate2 = "1"

download/Cargo.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,20 @@ license = "MIT/Apache-2.0"
99

1010
[features]
1111

12-
default = ["reqwest-backend"]
12+
default = ["reqwest-backend", "reqwest-rustls-tls", "reqwest-default-tls"]
1313

1414
curl-backend = ["curl"]
1515
reqwest-backend = ["reqwest", "env_proxy", "lazy_static"]
16+
reqwest-default-tls = ["reqwest/default-tls"]
17+
reqwest-rustls-tls = ["reqwest/rustls-tls"]
1618

1719
[dependencies]
1820
error-chain = "0.12"
1921
url = "2.1"
2022
curl = { version = "0.4.11", optional = true }
2123
env_proxy = { version = "0.4.1", optional = true }
2224
lazy_static = { version = "1.0", optional = true }
23-
reqwest = { version = "0.10", features = ["blocking", "gzip", "socks"], optional = true }
25+
reqwest = { version = "0.10", default-features = false, features = ["blocking", "gzip", "socks"], optional = true }
2426

2527
[dev-dependencies]
2628
hyper = { version = "0.13", default-features = false, features = ["tcp"] }

download/src/lib.rs

Lines changed: 55 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,13 @@ pub use crate::errors::*;
1010
#[derive(Debug, Copy, Clone)]
1111
pub 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")]
250256
pub 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

Comments
 (0)