Auto merge of #5085 - matklad:rust-1.25.0-tls, r=alexcrichton

[beta] warn about TLS for github specifically

Backport of https://github.com/rust-lang/cargo/pull/5069 to beta

r? @alexcrichton
This commit is contained in:
bors 2018-02-26 21:17:55 +00:00
commit 41480f5cc5
3 changed files with 51 additions and 13 deletions

View File

@ -591,7 +591,7 @@ pub fn with_fetch_options(git_config: &git2::Config,
-> CargoResult<()>
{
let mut progress = Progress::new("Fetch", config);
network::with_retry(config, || {
network::with_retry(config, url, || {
with_authentication(url.as_str(), git_config, |f| {
let mut rcb = git2::RemoteCallbacks::new();
rcb.credentials(f);

View File

@ -224,14 +224,13 @@ impl<'cfg> RegistryData for RemoteRegistry<'cfg> {
// TODO: don't download into memory, but ensure that if we ctrl-c a
// download we should resume either from the start or the middle
// on the next time
let url = url.to_string();
let mut handle = self.config.http()?.borrow_mut();
handle.get(true)?;
handle.url(&url)?;
handle.url(&url.to_string())?;
handle.follow_location(true)?;
let mut state = Sha256::new();
let mut body = Vec::new();
network::with_retry(self.config, || {
network::with_retry(self.config, &url, || {
state = Sha256::new();
body = Vec::new();
let mut pb = Progress::new("Fetch", self.config);
@ -250,8 +249,10 @@ impl<'cfg> RegistryData for RemoteRegistry<'cfg> {
}
let code = handle.response_code()?;
if code != 200 && code != 0 {
let url = handle.effective_url()?.unwrap_or(&url);
Err(HttpNot200 { code, url: url.to_string() }.into())
let url = handle.effective_url()?
.map(|url| url.to_string())
.unwrap_or_else(|| url.to_string());
Err(HttpNot200 { code, url }.into())
} else {
Ok(())
}

View File

@ -1,5 +1,6 @@
use curl;
use git2;
use url::Url;
use failure::Error;
@ -33,6 +34,35 @@ fn maybe_spurious(err: &Error) -> bool {
false
}
/// Suggest the user to update their windows 7 to support modern TLS versions.
/// See https://github.com/rust-lang/cargo/issues/5066 for details.
#[cfg(windows)]
fn should_warn_about_old_tls_for_win7(url: &Url, err: &Error) -> bool {
let is_github = url.host_str() == Some("github.com");
let is_cert_error = err.causes()
.filter_map(|e| e.downcast_ref::<git2::Error>())
.find(|e| e.class() == git2::ErrorClass::Net && e.code() == git2::ErrorCode::Certificate)
.is_some();
is_github && is_cert_error
}
#[cfg(not(windows))]
fn should_warn_about_old_tls_for_win7(_url: &Url, _err: &Error) -> bool {
false
}
const WIN7_TLS_WARNING: &str = "\
Certificate check failure might be caused by outdated TLS on older versions of Windows.
If you are using Windows 7, Windows Server 2008 R2 or Windows Server 2012,
please follow these instructions to enable more secure TLS:
https://support.microsoft.com/en-us/help/3140245/
See https://github.com/rust-lang/cargo/issues/5066 for details.
";
/// Wrapper method for network call retry logic.
///
/// Retry counts provided by Config object `net.retry`. Config shell outputs
@ -44,9 +74,9 @@ fn maybe_spurious(err: &Error) -> bool {
///
/// ```ignore
/// use util::network;
/// cargo_result = network.with_retry(&config, || something.download());
/// cargo_result = network::with_retry(&config, || something.download());
/// ```
pub fn with_retry<T, F>(config: &Config, mut callback: F) -> CargoResult<T>
pub fn with_retry<T, F>(config: &Config, url: &Url, mut callback: F) -> CargoResult<T>
where F: FnMut() -> CargoResult<T>
{
let mut remaining = config.net_retry()?;
@ -54,9 +84,14 @@ pub fn with_retry<T, F>(config: &Config, mut callback: F) -> CargoResult<T>
match callback() {
Ok(ret) => return Ok(ret),
Err(ref e) if maybe_spurious(e) && remaining > 0 => {
let msg = format!("spurious network error ({} tries \
remaining): {}", remaining, e);
config.shell().warn(msg)?;
config.shell().warn(
format!("spurious network error ({} tries remaining): {}", remaining, e)
)?;
if should_warn_about_old_tls_for_win7(url, e) {
config.shell().warn(WIN7_TLS_WARNING)?;
}
remaining -= 1;
}
//todo impl from
@ -71,7 +106,8 @@ fn with_retry_repeats_the_call_then_works() {
let error2 = HttpNot200 { code: 502, url: "Uri".to_string() }.into();
let mut results: Vec<CargoResult<()>> = vec![Ok(()), Err(error1), Err(error2)];
let config = Config::default().unwrap();
let result = with_retry(&config, || results.pop().unwrap());
let url = "http://example.com".parse().unwrap();
let result = with_retry(&config, &url, || results.pop().unwrap());
assert_eq!(result.unwrap(), ())
}
@ -87,6 +123,7 @@ fn with_retry_finds_nested_spurious_errors() {
let error2 = CargoError::from(error2.context("A second chained error"));
let mut results: Vec<CargoResult<()>> = vec![Ok(()), Err(error1), Err(error2)];
let config = Config::default().unwrap();
let result = with_retry(&config, || results.pop().unwrap());
let url = "http://example.com".parse().unwrap();
let result = with_retry(&config, &url, || results.pop().unwrap());
assert_eq!(result.unwrap(), ())
}