From 268097e90556929320d6df8de4692968bb2b946a Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 10 May 2016 08:32:11 -0700 Subject: [PATCH 1/6] Migrate to using libcurl for now instead of hyper Unfortunately the move to rust-native-tls has had some hiccups on Windows and Hyper also currently doesn't support features like HTTP proxies (but support's coming soon!). For now this temporarily moves over to using libcurl to weed out these problems until we get to a point where we're hyper's features are more filled out. This also somewhat aligns with Cargo as well which is using libcurl currently. This does not use the `curl` crate on crates.io because it doesn't support streaming downloads. Instead I've got an in-progress rewrite which is just binding much more directly to libcurl's APIs (e.g. exposing the callback functions directly). This branch is in a git repo currently and I hope to upstream it to curl-rust soon as well. --- Cargo.lock | 237 ++--------------------- src/rustup-cli/common.rs | 2 +- src/rustup-cli/self_update.rs | 5 +- src/rustup-dist/src/dist.rs | 7 +- src/rustup-dist/src/download.rs | 8 +- src/rustup-dist/src/manifestation.rs | 3 +- src/rustup-mock/src/dist.rs | 1 - src/rustup-utils/Cargo.toml | 7 +- src/rustup-utils/src/errors.rs | 13 +- src/rustup-utils/src/lib.rs | 4 +- src/rustup-utils/src/notifications.rs | 5 +- src/rustup-utils/src/raw.rs | 267 ++++++++------------------ src/rustup-utils/src/utils.rs | 38 ++-- src/rustup/config.rs | 5 +- src/rustup/toolchain.rs | 14 +- 15 files changed, 161 insertions(+), 455 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 24f2dd548b..341acc8065 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -84,11 +84,6 @@ name = "bitflags" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "bitflags" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "cfg-if" version = "0.1.0" @@ -108,38 +103,25 @@ dependencies = [ ] [[package]] -name = "cookie" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "core-foundation" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" +name = "curl" +version = "0.2.18" +source = "git+https://github.com/alexcrichton/curl-rust?branch=rewrite#3695aa16da4b3777011a94331e237b97b49fb84f" dependencies = [ - "core-foundation-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "curl-sys 0.1.34 (git+https://github.com/alexcrichton/curl-rust?branch=rewrite)", "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "core-foundation-sys" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" +name = "curl-sys" +version = "0.1.34" +source = "git+https://github.com/alexcrichton/curl-rust?branch=rewrite#3695aa16da4b3777011a94331e237b97b49fb84f" dependencies = [ + "gcc 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crypt32-sys" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libz-sys 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -188,39 +170,6 @@ dependencies = [ "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "hpack" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "httparse" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "hyper" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cookie 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "httparse 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "mime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", - "solicit 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "traitobject 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "idna" version = "0.1.0" @@ -263,21 +212,11 @@ dependencies = [ "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "language-tags" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "lazy_static" version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "lazy_static" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "libc" version = "0.2.11" @@ -292,9 +231,14 @@ dependencies = [ ] [[package]] -name = "log" -version = "0.3.6" +name = "libz-sys" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "gcc 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "markdown" @@ -318,14 +262,6 @@ dependencies = [ "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "mime" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "miniz-sys" version = "0.1.7" @@ -335,25 +271,6 @@ dependencies = [ "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "native-tls" -version = "0.1.0" -source = "git+https://github.com/sfackler/rust-native-tls.git#a3d03b6ab5cee02313ff79a9e96a10b0c9b9e28a" -dependencies = [ - "openssl 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-verify 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "schannel 0.0.2 (git+https://github.com/sfackler/schannel-rs)", - "security-framework 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "num_cpus" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "ole32-sys" version = "0.2.0" @@ -363,19 +280,6 @@ dependencies = [ "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "openssl" -version = "0.7.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "gcc 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys-extras 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "openssl-sys" version = "0.7.11" @@ -388,24 +292,6 @@ dependencies = [ "user32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "openssl-sys-extras" -version = "0.7.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "gcc 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "openssl-verify" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "openssl 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "pipeline" version = "0.5.0" @@ -454,14 +340,6 @@ name = "rustc-serialize" version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "rustc_version" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "rustup-dist" version = "0.1.10" @@ -505,11 +383,10 @@ name = "rustup-utils" version = "0.1.10" dependencies = [ "advapi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "curl 0.2.18 (git+https://github.com/alexcrichton/curl-rust?branch=rewrite)", "error-chain 0.1.10", - "hyper 0.9.4 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "native-tls 0.1.0 (git+https://github.com/sfackler/rust-native-tls.git)", "ole32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-sys 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", @@ -517,62 +394,17 @@ dependencies = [ "scopeguard 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "shell32-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "userenv-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "winreg 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "schannel" -version = "0.0.2" -source = "git+https://github.com/sfackler/schannel-rs#d16f7949939777375bae9716f098145b151c28e5" -dependencies = [ - "crypt32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", - "secur32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "scopeguard" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "secur32-sys" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "security-framework" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "core-foundation 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "core-foundation-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "security-framework-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "security-framework-sys" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "core-foundation-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "semver" -version = "0.1.20" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "sha2" version = "0.1.2" @@ -590,15 +422,6 @@ dependencies = [ "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "solicit" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "hpack 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "strsim" version = "0.4.1" @@ -665,24 +488,6 @@ dependencies = [ "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "traitobject" -version = "0.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "typeable" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "unicase" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "unicode-bidi" version = "0.2.3" diff --git a/src/rustup-cli/common.rs b/src/rustup-cli/common.rs index 9bd92fbc1e..8c0428b8bc 100644 --- a/src/rustup-cli/common.rs +++ b/src/rustup-cli/common.rs @@ -6,7 +6,7 @@ use errors::*; use rustup_utils::utils; use rustup_utils::notify::NotificationLevel; use self_update; -use std::io::{Write, Read, BufRead}; +use std::io::{Write, BufRead}; use std::process::Command; use std::{cmp, iter}; use std::str::FromStr; diff --git a/src/rustup-cli/self_update.rs b/src/rustup-cli/self_update.rs index f071bc295a..fd40cc649e 100644 --- a/src/rustup-cli/self_update.rs +++ b/src/rustup-cli/self_update.rs @@ -31,7 +31,6 @@ //! and racy on Windows. use common::{self, Confirm}; -use itertools::Itertools; use rustup::{NotifyHandler}; use errors::*; use rustup_dist::dist; @@ -1069,7 +1068,7 @@ pub fn prepare_update() -> Result> { info!("checking for self-updates"); let hash_url = try!(utils::parse_url(&(url.clone() + ".sha256"))); let hash_file = tempdir.path().join("hash"); - try!(utils::download_file(hash_url, &hash_file, None, ntfy!(&NotifyHandler::none()))); + try!(utils::download_file(&hash_url, &hash_file, None, ntfy!(&NotifyHandler::none()))); let mut latest_hash = try!(utils::read_file("hash", &hash_file)); latest_hash.truncate(64); @@ -1085,7 +1084,7 @@ pub fn prepare_update() -> Result> { // Download new version info!("downloading self-update"); let mut hasher = Sha256::new(); - try!(utils::download_file(download_url, + try!(utils::download_file(&download_url, &setup_path, Some(&mut hasher), ntfy!(&NotifyHandler::none()))); diff --git a/src/rustup-dist/src/dist.rs b/src/rustup-dist/src/dist.rs index a1d3ca351b..f5279bd151 100644 --- a/src/rustup-dist/src/dist.rs +++ b/src/rustup-dist/src/dist.rs @@ -13,7 +13,6 @@ use std::fmt; use regex::Regex; use sha2::{Sha256, Digest}; -use itertools::Itertools; pub const DEFAULT_DIST_ROOT: &'static str = "https://static.rust-lang.org/dist"; pub const UPDATE_HASH_LEN: usize = 20; @@ -76,7 +75,7 @@ impl TargetTriple { if let Some(triple) = option_env!("RUSTUP_OVERRIDE_HOST_TRIPLE") { TargetTriple::from_str(triple) } else { - TargetTriple::from_str(include_str!(concat!(env!("OUT_DIR"), "/target.txt"))) + TargetTriple::from_str(include_str!(concat!(env!("OUT_DIR"), "/target.txt"))) } } } @@ -342,7 +341,7 @@ pub fn download_and_check<'a>(url_str: &str, let file = try!(cfg.temp_cfg.new_file_with_ext("", ext)); let mut hasher = Sha256::new(); - try!(utils::download_file(url, &file, Some(&mut hasher), ntfy!(&cfg.notify_handler))); + try!(utils::download_file(&url, &file, Some(&mut hasher), ntfy!(&cfg.notify_handler))); let actual_hash = hasher.result_str(); if hash != actual_hash { @@ -372,7 +371,7 @@ pub fn download_hash(url: &str, cfg: DownloadCfg) -> Result { let hash_url = try!(utils::parse_url(&(url.to_owned() + ".sha256"))); let hash_file = try!(cfg.temp_cfg.new_file()); - try!(utils::download_file(hash_url, &hash_file, None, ntfy!(&cfg.notify_handler))); + try!(utils::download_file(&hash_url, &hash_file, None, ntfy!(&cfg.notify_handler))); Ok(try!(utils::read_file("hash", &hash_file).map(|s| s[0..64].to_owned()))) } diff --git a/src/rustup-dist/src/download.rs b/src/rustup-dist/src/download.rs index eadeceb2fd..09b9ea907e 100644 --- a/src/rustup-dist/src/download.rs +++ b/src/rustup-dist/src/download.rs @@ -22,14 +22,14 @@ impl<'a> DownloadCfg<'a> { let sig_url = try!(utils::parse_url(&format!("{}.asc", url))); let sig_file = try!(self.temp_cfg.new_file()); - try!(utils::download_file(sig_url, &sig_file, None, ntfy!(&self.notify_handler))); + try!(utils::download_file(&sig_url, &sig_file, None, ntfy!(&self.notify_handler))); let target_url = try!(utils::parse_url(url)); let target_file = try!(self.temp_cfg.new_file()); { let target_filename: &Path = &target_file; - try!(utils::download_file(target_url, + try!(utils::download_file(&target_url, &target_file, None, ntfy!(&self.notify_handler))); @@ -62,14 +62,14 @@ impl<'a> DownloadCfg<'a> { let hash_url = try!(utils::parse_url(&format!("{}.sha256", url))); let hash_file = try!(self.temp_cfg.new_file()); - try!(utils::download_file(hash_url, &hash_file, None, ntfy!(&self.notify_handler))); + try!(utils::download_file(&hash_url, &hash_file, None, ntfy!(&self.notify_handler))); let hash = try!(utils::read_file("hash", &hash_file).map(|s| s[0..64].to_owned())); let mut hasher = Sha256::new(); let target_url = try!(utils::parse_url(url)); let target_file = try!(self.temp_cfg.new_file()); - try!(utils::download_file(target_url, + try!(utils::download_file(&target_url, &target_file, Some(&mut hasher), ntfy!(&self.notify_handler))); diff --git a/src/rustup-dist/src/manifestation.rs b/src/rustup-dist/src/manifestation.rs index 976c5ebfaf..ee82fcfdab 100644 --- a/src/rustup-dist/src/manifestation.rs +++ b/src/rustup-dist/src/manifestation.rs @@ -11,7 +11,6 @@ use notifications::*; use rustup_utils::utils; use prefix::InstallPrefix; use sha2::{Sha256, Digest}; -use itertools::Itertools; use std::path::Path; pub const DIST_MANIFEST: &'static str = "multirust-channel-manifest.toml"; @@ -136,7 +135,7 @@ impl Manifestation { let url_url = try!(utils::parse_url(&url)); let mut hasher = Sha256::new(); - try!(utils::download_file(url_url, &temp_file, Some(&mut hasher), ntfy!(¬ify_handler)) + try!(utils::download_file(&url_url, &temp_file, Some(&mut hasher), ntfy!(¬ify_handler)) .chain_err(|| ErrorKind::ComponentDownloadFailed(component.clone()))); let actual_hash = hasher.result_str(); diff --git a/src/rustup-mock/src/dist.rs b/src/rustup-mock/src/dist.rs index acd5604197..a8d142b0a0 100644 --- a/src/rustup-mock/src/dist.rs +++ b/src/rustup-mock/src/dist.rs @@ -9,7 +9,6 @@ use std::collections::HashMap; use std::io::{Read, Write}; use tempdir::TempDir; use sha2::{Sha256, Digest}; -use itertools::Itertools; use toml; use flate2; use tar; diff --git a/src/rustup-utils/Cargo.toml b/src/rustup-utils/Cargo.toml index 13d672c54a..215eb46da3 100644 --- a/src/rustup-utils/Cargo.toml +++ b/src/rustup-utils/Cargo.toml @@ -16,9 +16,10 @@ rand = "0.3.11" scopeguard = "0.1.2" error-chain = { path = "../error-chain", version = "0.1.10" } libc = "0.2.0" -native-tls = { git = "https://github.com/sfackler/rust-native-tls.git" } rustc-serialize = "0.3.19" sha2 = "0.1.2" +curl = { git = "https://github.com/alexcrichton/curl-rust", branch = "rewrite" } +url = "1.1" [target.'cfg(not(any(target_os = "windows", target_os = "macos")))'.dependencies] openssl-sys = "0.7.11" @@ -31,7 +32,3 @@ ole32-sys = "0.2.0" kernel32-sys = "0.2.1" advapi32-sys = "0.2.0" userenv-sys = "0.2.0" - -[dependencies.hyper] -version = "0.9.2" -default-features = false diff --git a/src/rustup-utils/src/errors.rs b/src/rustup-utils/src/errors.rs index 1c54032e63..4088c3bd4c 100644 --- a/src/rustup-utils/src/errors.rs +++ b/src/rustup-utils/src/errors.rs @@ -1,6 +1,7 @@ use std::path::PathBuf; use std::ffi::OsString; -use hyper; +use curl; +use url::Url; error_chain! { types { @@ -67,19 +68,23 @@ error_chain! { description("could not rename directory") display("could not rename {} directory from '{}' to '{}'", name, src.display(), dest.display()) } - HttpStatus(e: hyper::status::StatusCode) { + HttpError(e: curl::Error) { + description("http request did not succeed") + display("http request returned failure: {}", e) + } + HttpStatus(e: u32) { description("http request returned an unsuccessful status code") display("http request returned an unsuccessful status code: {}", e) } DownloadingFile { - url: hyper::Url, + url: Url, path: PathBuf, } { description("could not download file") display("could not download file from '{}' to '{}", url, path.display()) } Download404 { - url: hyper::Url, + url: Url, path: PathBuf, } { description("could not download file") diff --git a/src/rustup-utils/src/lib.rs b/src/rustup-utils/src/lib.rs index b1e3a2b807..3e9f088644 100644 --- a/src/rustup-utils/src/lib.rs +++ b/src/rustup-utils/src/lib.rs @@ -2,16 +2,16 @@ #![feature(fundamental)] #![recursion_limit = "1024"] // for error_chain! -extern crate hyper; +extern crate curl; extern crate rand; extern crate scopeguard; #[macro_use] extern crate error_chain; -extern crate native_tls; extern crate rustc_serialize; extern crate sha2; #[cfg(not(any(target_os = "windows", target_os = "macos")))] extern crate openssl_sys; +extern crate url; #[cfg(windows)] extern crate winapi; diff --git a/src/rustup-utils/src/notifications.rs b/src/rustup-utils/src/notifications.rs index 47671b9cb6..8dcc880e92 100644 --- a/src/rustup-utils/src/notifications.rs +++ b/src/rustup-utils/src/notifications.rs @@ -1,6 +1,7 @@ use std::path::Path; use std::fmt::{self, Display}; -use hyper; + +use url::Url; use notify::{self, NotificationLevel, Notifyable}; @@ -10,7 +11,7 @@ pub enum Notification<'a> { LinkingDirectory(&'a Path, &'a Path), CopyingDirectory(&'a Path, &'a Path), RemovingDirectory(&'a str, &'a Path), - DownloadingFile(&'a hyper::Url, &'a Path), + DownloadingFile(&'a Url, &'a Path), /// Received the Content-Length of the to-be downloaded data. DownloadContentLengthReceived(u64), /// Received some data. diff --git a/src/rustup-utils/src/raw.rs b/src/rustup-utils/src/raw.rs index 5ce2e1f4c5..2cfad56b2b 100644 --- a/src/rustup-utils/src/raw.rs +++ b/src/rustup-utils/src/raw.rs @@ -1,19 +1,22 @@ use notifications::NotifyHandler; +use std::cell::RefCell; +use std::char::from_u32; use std::error; +use std::ffi::{OsStr, OsString}; +use std::fmt; use std::fs; -use std::path::Path; -use std::io; -use std::char::from_u32; use std::io::Write; +use std::io; +use std::path::Path; use std::process::{Command, Stdio, ExitStatus}; -use std::ffi::{OsStr, OsString}; -use std::fmt; +use std::str; use std::thread; use std::time::Duration; -use hyper::{self, Client}; +use curl::easy::Easy; use sha2::{Sha256, Digest}; use errors::*; +use url::Url; use rand::random; @@ -152,161 +155,93 @@ pub fn tee_file(path: &Path, mut w: &mut W) -> io::Result<()> { } } -pub fn download_file>(url: hyper::Url, - path: P, - mut hasher: Option<&mut Sha256>, - notify_handler: NotifyHandler) - -> Result<()> { - - // Short-circuit hyper for the "file:" URL scheme - if try!(download_from_file_url(&url, &path, &mut hasher)) { - return Ok(()); - } - - use hyper::error::Result as HyperResult; - use hyper::header::ContentLength; - use hyper::net::{SslClient, NetworkStream, HttpsConnector}; - use native_tls; +pub fn download_file(url: &Url, + path: &Path, + mut hasher: Option<&mut Sha256>, + notify_handler: NotifyHandler) + -> Result<()> { use notifications::Notification; - use std::io::Result as IoResult; - use std::io::{Read, Write}; - use std::net::{SocketAddr, Shutdown}; - use std::sync::{Arc, Mutex}; - - // The Hyper HTTP client - let client; - - if url.scheme() == "https" { - - // All the following is adapter code to use native_tls with hyper. - - struct NativeSslClient; - - impl SslClient for NativeSslClient { - type Stream = NativeSslStream; + use std::io::Write; - fn wrap_client(&self, stream: T, host: &str) -> HyperResult { - use native_tls::ClientBuilder as TlsClientBuilder; - use hyper::error::Error as HyperError; + maybe_init_certs(); - let mut ssl_builder = try!(TlsClientBuilder::new() - .map_err(|e| HyperError::Ssl(Box::new(e)))); - let ssl_stream = try!(ssl_builder.handshake(host, stream) - .map_err(|e| HyperError::Ssl(Box::new(e)))); - - Ok(NativeSslStream(Arc::new(Mutex::new(ssl_stream)))) - } - } - - #[derive(Clone)] - struct NativeSslStream(Arc>>); - - #[derive(Debug)] - struct NativeSslPoisonError; + let mut file = try!(fs::File::create(&path).chain_err( + || "error creating file for download")); + let fserr = RefCell::new(None); - impl ::std::error::Error for NativeSslPoisonError { - fn description(&self) -> &str { "mutex poisoned during TLS operation" } + // Data callback for libcurl which is called with data that's downloaded. We + // just feed it into our hasher and also write it out to disk. + let mut ondata = |data: &[u8]| { + if let Some(ref mut h) = hasher { + h.input(data); } - - impl ::std::fmt::Display for NativeSslPoisonError { - fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::result::Result<(), ::std::fmt::Error> { - f.write_str(::std::error::Error::description(self)) - } - } - - impl NetworkStream for NativeSslStream - where T: NetworkStream - { - fn peer_addr(&mut self) -> IoResult { - self.0.lock() - .map_err(|_| io::Error::new(io::ErrorKind::Other, NativeSslPoisonError)) - .and_then(|mut t| t.get_mut().peer_addr()) - } - fn set_read_timeout(&self, dur: Option) -> IoResult<()> { - self.0.lock() - .map_err(|_| io::Error::new(io::ErrorKind::Other, NativeSslPoisonError)) - .and_then(|t| t.get_ref().set_read_timeout(dur)) - } - fn set_write_timeout(&self, dur: Option) -> IoResult<()> { - self.0.lock() - .map_err(|_| io::Error::new(io::ErrorKind::Other, NativeSslPoisonError)) - .and_then(|t| t.get_ref().set_write_timeout(dur)) - } - fn close(&mut self, how: Shutdown) -> IoResult<()> { - self.0.lock() - .map_err(|_| io::Error::new(io::ErrorKind::Other, NativeSslPoisonError)) - .and_then(|mut t| t.get_mut().close(how)) + notify_handler.call(Notification::DownloadDataReceived(data.len())); + match file.write_all(data) { + Ok(()) => data.len(), + Err(e) => { + *fserr.borrow_mut() = Some(e); + 0 } } + }; - impl Read for NativeSslStream - where T: Read + Write - { - fn read(&mut self, buf: &mut [u8]) -> IoResult { - self.0.lock() - .map_err(|_| io::Error::new(io::ErrorKind::Other, NativeSslPoisonError)) - .and_then(|mut t| t.read(buf)) + // Listen for headers and parse out a `Content-Length` if it comes so we + // know how much we're downloading. + let mut onheader = |data: &[u8]| { + if let Ok(data) = str::from_utf8(data) { + let prefix = "Content-Length: "; + if data.starts_with(prefix) { + if let Ok(s) = data[prefix.len()..].trim().parse() { + notify_handler.call(Notification::DownloadContentLengthReceived(s)); + } } } + true + }; - impl Write for NativeSslStream - where T: Read + Write - { - fn write(&mut self, buf: &[u8]) -> IoResult { - self.0.lock() - .map_err(|_| io::Error::new(io::ErrorKind::Other, NativeSslPoisonError)) - .and_then(|mut t| t.write(buf)) - } - fn flush(&mut self) -> IoResult<()> { - self.0.lock() - .map_err(|_| io::Error::new(io::ErrorKind::Other, NativeSslPoisonError)) - .and_then(|mut t| t.flush()) - } + // Fetch either a cached libcurl handle (which will preserve open + // connections) or create a new one if it isn't listed. + // + // Once we've acquired it, reset the lifetime from 'static to our local + // scope. + thread_local!(static EASY: RefCell>> = RefCell::new(None)); + let handle = EASY.with(|e| e.borrow_mut().take()).unwrap_or(Easy::new()); + let mut handle = handle.reset_lifetime(); + + try!(handle.url(&url.to_string()).chain_err(|| "failed to set url")); + try!(handle.follow_location(true).chain_err(|| "failed to set follow redirects")); + try!(handle.write_function(&mut ondata).chain_err(|| "failed to set write")); + try!(handle.header_function(&mut onheader).chain_err(|| "failed to set header")); + + // Take at most 30s to connect + try!(handle.connect_timeout(Duration::new(30, 0)).chain_err(|| "failed to set connect timeout")); + + // Fail if less than 10 bytes are transferred every 30 seconds + try!(handle.low_speed_limit(10).chain_err(|| "failed to set low speed limit")); + try!(handle.low_speed_time(Duration::new(30, 0)).chain_err(|| "failed to set low speed time")); + + // If an error happens check to see if we had a filesystem error up in + // `fserr`, but we always want to punt it up. + try!(handle.perform().or_else(|e| { + match fserr.borrow_mut().take() { + Some(fs) => Err(fs).chain_err(|| ErrorKind::HttpError(e)), + None => Err(ErrorKind::HttpError(e).into()) } + })); - maybe_init_certs(); - - // Connect with hyper + native_tls - client = Client::with_connector(HttpsConnector::new(NativeSslClient)); - } else if url.scheme() == "http" { - client = Client::new(); - } else { - return Err(format!("unsupported URL scheme: '{}'", url.scheme()).into()); - } - - let mut res = try!(client.get(url).send() - .chain_err(|| "failed to make network request")); - if res.status != hyper::Ok { - return Err(ErrorKind::HttpStatus(res.status).into()); - } - - let buffer_size = 0x10000; - let mut buffer = vec![0u8; buffer_size]; - - let mut file = try!(fs::File::create(&path).chain_err( - || "error creating file for download")); - - if let Some(len) = res.headers.get::().cloned() { - notify_handler.call(Notification::DownloadContentLengthReceived(len.0)); + // If we didn't get a 200 or 0 ("OK" for files) then return an error + let code = try!(handle.response_code().chain_err(|| "failed to get response code")); + if code != 200 && code != 0 { + return Err(ErrorKind::HttpStatus(code).into()); } - loop { - let bytes_read = try!(io::Read::read(&mut res, &mut buffer) - .chain_err(|| "error reading from socket")); - - if bytes_read != 0 { - if let Some(ref mut h) = hasher { - h.input(&buffer[0..bytes_read]); - } - try!(io::Write::write_all(&mut file, &mut buffer[0..bytes_read]) - .chain_err(|| "unable to write download to disk")); - notify_handler.call(Notification::DownloadDataReceived(bytes_read)); - } else { - try!(file.sync_data().chain_err(|| "unable to sync download to disk")); - notify_handler.call(Notification::DownloadFinished); - return Ok(()); - } - } + // If everything worked out, put our handle back (with a reset to 'static) + // and then send off a notification for the completed download. + EASY.with(|e| { + *e.borrow_mut() = Some(handle.reset_lifetime()); + }); + notify_handler.call(Notification::DownloadFinished); + Ok(()) } // Tell our statically-linked OpenSSL where to find root certs @@ -323,42 +258,6 @@ fn maybe_init_certs() { #[cfg(any(target_os = "windows", target_os = "macos"))] fn maybe_init_certs() { } -fn download_from_file_url>(url: &hyper::Url, - path: P, - hasher: &mut Option<&mut Sha256>) - -> Result { - // The file scheme is mostly for use by tests to mock the dist server - if url.scheme() == "file" { - let src = try!(url.to_file_path() - .map_err(|_| Error::from(format!("bogus file url: '{}'", url)))); - if !is_file(&src) { - // Because some of multirust's logic depends on checking - // the error when a downloaded file doesn't exist, make - // the file case return the same error value as the - // network case. - return Err(ErrorKind::HttpStatus(hyper::status::StatusCode::NotFound).into()); - } - try!(fs::copy(&src, path.as_ref()).chain_err(|| "failure copying file")); - - if let Some(ref mut h) = *hasher { - let ref mut f = try!(fs::File::open(path.as_ref()) - .chain_err(|| "unable to open downloaded file")); - - let ref mut buffer = vec![0u8; 0x10000]; - loop { - let bytes_read = try!(io::Read::read(f, buffer) - .chain_err(|| "unable to read downloaded file")); - if bytes_read == 0 { break } - h.input(&buffer[0..bytes_read]); - } - } - - Ok(true) - } else { - Ok(false) - } -} - pub fn symlink_dir(src: &Path, dest: &Path) -> io::Result<()> { #[cfg(windows)] fn symlink_dir_inner(src: &Path, dest: &Path) -> io::Result<()> { @@ -429,7 +328,7 @@ fn symlink_junction_inner(target: &Path, junction: &Path) -> io::Result<()> { OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, ptr::null_mut()); - + let mut data = [0u8; MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; let mut db = data.as_mut_ptr() as *mut REPARSE_MOUNTPOINT_DATA_BUFFER; @@ -458,7 +357,7 @@ fn symlink_junction_inner(target: &Path, junction: &Path) -> io::Result<()> { ptr::null_mut(), 0, &mut ret, ptr::null_mut()); - + if res == 0 { Err(io::Error::last_os_error()) } else { diff --git a/src/rustup-utils/src/utils.rs b/src/rustup-utils/src/utils.rs index bb32a4a23f..5ca392211b 100644 --- a/src/rustup-utils/src/utils.rs +++ b/src/rustup-utils/src/utils.rs @@ -5,9 +5,7 @@ use std::io::{self, Write}; use std::process::Command; use std::ffi::OsString; use std::env; -use hyper; use sha2::Sha256; -use notify::Notifyable; use notifications::{Notification, NotifyHandler}; use raw; #[cfg(windows)] @@ -15,6 +13,7 @@ use winapi::DWORD; #[cfg(windows)] use winreg; use std::cmp::Ord; +use url::Url; pub use raw::{is_directory, is_file, path_exists, if_not_empty, random_string, prefix_arg, has_cmd, find_cmd}; @@ -140,34 +139,41 @@ pub fn tee_file(name: &'static str, path: &Path, w: &mut W) -> Res }) } -pub fn download_file(url: hyper::Url, +pub fn download_file(url: &Url, path: &Path, hasher: Option<&mut Sha256>, notify_handler: NotifyHandler) -> Result<()> { - use hyper::status::StatusCode::NotFound; - - notify_handler.call(Notification::DownloadingFile(&url, path)); - match raw::download_file(url.clone(), path, hasher, notify_handler) { + notify_handler.call(Notification::DownloadingFile(url, path)); + match raw::download_file(url, path, hasher, notify_handler) { Ok(_) => Ok(()), - Err(e @ Error(ErrorKind::HttpStatus(NotFound), _)) => { - Err(e).chain_err(|| ErrorKind::Download404 { - url: url, - path: path.to_path_buf(), + Err(Error(ErrorKind::HttpError(e), d)) => { + if e.is_file_couldnt_read_file() { + return Err(Error(ErrorKind::HttpError(e), d)).chain_err(|| { + ErrorKind::Download404 { + url: url.clone(), + path: path.to_path_buf(), + } + }) + } + Err(Error(ErrorKind::HttpError(e), d)).chain_err(|| { + ErrorKind::DownloadingFile { + url: url.clone(), + path: path.to_path_buf(), + } }) } Err(e) => { Err(e).chain_err(|| ErrorKind::DownloadingFile { - url: url, + url: url.clone(), path: path.to_path_buf(), }) } } } -pub fn parse_url(url: &str) -> Result { - hyper::Url::parse(url) - .chain_err(|| ErrorKind::InvalidUrl { url: url.to_owned() }) +pub fn parse_url(url: &str) -> Result { + Url::parse(url).chain_err(|| format!("failed to parse url: {}", url)) } pub fn cmd_status(name: &'static str, cmd: &mut Command) -> Result<()> { @@ -448,7 +454,7 @@ pub fn multirust_home() -> Result { pub fn format_path_for_display(path: &str) -> String { let unc_present = path.find(r"\\?\"); - + match unc_present { None => path.to_owned(), Some(_) => path[4..].to_owned(), diff --git a/src/rustup/config.rs b/src/rustup/config.rs index 916eb19b3e..bd8e062b67 100644 --- a/src/rustup/config.rs +++ b/src/rustup/config.rs @@ -4,9 +4,6 @@ use std::env; use std::io; use std::process::Command; use std::fmt::{self, Display}; -use std::str::FromStr; - -use itertools::Itertools; use errors::*; use notifications::*; @@ -406,7 +403,7 @@ impl Cfg { fn enable_telemetry(&self) -> Result<()> { let work_file = try!(self.temp_cfg.new_file()); - + let _ = utils::ensure_dir_exists("telemetry", &self.multirust_dir.join("telemetry"), ntfy!(&NotifyHandler::none())); try!(utils::write_file("temp", &work_file, "")); diff --git a/src/rustup/toolchain.rs b/src/rustup/toolchain.rs index 113f33cc78..fe83df6db6 100644 --- a/src/rustup/toolchain.rs +++ b/src/rustup/toolchain.rs @@ -158,7 +158,7 @@ impl<'a> Toolchain<'a> { self.install(InstallMethod::Dist(&try!(self.desc()), update_hash.as_ref().map(|p| &**p), self.download_cfg())) - } + } pub fn install_from_dist_with_telemetry(&self) -> Result { let result = self.install_from_dist_inner(); @@ -169,12 +169,12 @@ impl<'a> Toolchain<'a> { success: true }; match self.telemetry.log_telemetry(te) { Ok(_) => Ok(us), - Err(e) => { + Err(e) => { self.cfg.notify_handler.call(Notification::TelemetryCleanupError(&e)); Ok(us) } } - } + } Err(e) => { let te = TelemetryEvent::ToolchainUpdate { toolchain: self.name().to_string() , success: true }; @@ -236,7 +236,7 @@ impl<'a> Toolchain<'a> { // Download to a local file let local_installer = try!(self.cfg.temp_cfg.new_file_with_ext("", ".tar.gz")); - try!(utils::download_file(url, + try!(utils::download_file(&url, &local_installer, None, ntfy!(&self.cfg.notify_handler))); @@ -404,19 +404,19 @@ impl<'a> Toolchain<'a> { match output { Ok(_) => { - let te = TelemetryEvent::ToolchainUpdate { toolchain: self.name.to_owned(), + let te = TelemetryEvent::ToolchainUpdate { toolchain: self.name.to_owned(), success: true }; match self.telemetry.log_telemetry(te) { Ok(_) => Ok(()), - Err(e) => { + Err(e) => { self.cfg.notify_handler.call(Notification::TelemetryCleanupError(&e)); Ok(()) } } }, Err(e) => { - let te = TelemetryEvent::ToolchainUpdate { toolchain: self.name.to_owned(), + let te = TelemetryEvent::ToolchainUpdate { toolchain: self.name.to_owned(), success: false }; let _ = self.telemetry.log_telemetry(te).map_err(|xe| { From 14230fd35061f7e8122bc89503430691c9d21a6d Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Wed, 11 May 2016 00:32:04 +0000 Subject: [PATCH 2/6] Delete mingw bins on appveyor --- appveyor.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index 154087f3be..687475bf40 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -24,6 +24,8 @@ install: # For -gnu builds if ($env:TARGET -match "-gnu$") { $env:PATH="$env:PATH;C:\msys64\mingw${env:BITS}\bin" + # Remove the mingw gcc to keep it from interfering with the build + Remove-Item -Recurse -Force "C:\rust\lib\rustlib\$env:TARGET\bin\" } # Print version info From 25105492b61084eae228b36a4ab8e4c46ec3fc26 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Tue, 10 May 2016 23:37:26 -0700 Subject: [PATCH 3/6] Add /usr/bin to appveyor path to find 'make' --- appveyor.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/appveyor.yml b/appveyor.yml index 687475bf40..e7996d891a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -23,6 +23,7 @@ install: # For -gnu builds if ($env:TARGET -match "-gnu$") { + $env:PATH="$env:PATH;C:\msys64\usr\bin" $env:PATH="$env:PATH;C:\msys64\mingw${env:BITS}\bin" # Remove the mingw gcc to keep it from interfering with the build Remove-Item -Recurse -Force "C:\rust\lib\rustlib\$env:TARGET\bin\" From d7bcf6d4fb0b3cb83d811c53b333e9079be37d13 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Wed, 11 May 2016 09:00:17 -0700 Subject: [PATCH 4/6] Switch the path order in appveyor CI --- appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index e7996d891a..8b5245b1fa 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -23,8 +23,8 @@ install: # For -gnu builds if ($env:TARGET -match "-gnu$") { - $env:PATH="$env:PATH;C:\msys64\usr\bin" - $env:PATH="$env:PATH;C:\msys64\mingw${env:BITS}\bin" + $env:PATH="C:\msys64\usr\bin;$env:PATH" + $env:PATH="C:\msys64\mingw${env:BITS}\bin;$env:PATH" # Remove the mingw gcc to keep it from interfering with the build Remove-Item -Recurse -Force "C:\rust\lib\rustlib\$env:TARGET\bin\" } From 31dc62a6d75cc354363c604d6d639dbf9c092b77 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Wed, 11 May 2016 09:35:10 -0700 Subject: [PATCH 5/6] Debug appveyor --- appveyor.yml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 8b5245b1fa..2c9f241afd 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,7 +1,7 @@ environment: matrix: - - TARGET: x86_64-pc-windows-msvc - - TARGET: i686-pc-windows-msvc + #- TARGET: x86_64-pc-windows-msvc + #- TARGET: i686-pc-windows-msvc - TARGET: x86_64-pc-windows-gnu BITS: 64 - TARGET: i686-pc-windows-gnu @@ -14,6 +14,12 @@ branches: - stable - auto +init: + - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) + +on_finish: + - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) + install: - ps: | # Install Rust From 65fe029b4b08814ea77a87b438d6674cf99e4984 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Wed, 11 May 2016 10:12:21 -0700 Subject: [PATCH 6/6] Try to use a custom i686 gnu toolchain on appveyor --- appveyor.yml | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 2c9f241afd..50bc032497 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -2,10 +2,13 @@ environment: matrix: #- TARGET: x86_64-pc-windows-msvc #- TARGET: i686-pc-windows-msvc - - TARGET: x86_64-pc-windows-gnu - BITS: 64 - TARGET: i686-pc-windows-gnu BITS: 32 + MINGW_URL: https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Personal%20Builds/mingw-builds/4.9.2/threads-win32/dwarf/i686-4.9.2-release-win32-dwarf-rt_v4-rev4.7z/download + MINGW_ARCHIVE: i686-4.9.2-release-win32-dwarf-rt_v4-rev4.7z + MINGW_DIR: mingw32 + - TARGET: x86_64-pc-windows-gnu + BITS: 64 access_token: secure: q8Wqx0brgfpOYFQqWauvucE2h0o1WYb41a3gKaCKV9QiE4eTz6qLNlqyC3mdsp4Q branches: @@ -21,6 +24,12 @@ on_finish: - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) install: + - if defined BITS set PATH=C:\msys64\mingw%BITS%\bin;C:\msys64\usr\bin;%PATH% + - if defined MINGW_ARCHIVE appveyor DownloadFile "%MINGW_URL%" -FileName "%MINGW_ARCHIVE%" + - if defined MINGW_ARCHIVE 7z x -y "%MINGW_ARCHIVE%" > nul + - if defined MINGW_ARCHIVE set PATH=%CD%\%MINGW_DIR%\bin;%PATH% + - if defined MINGW_ARCHIVE where gcc + - if defined MINGW_ARCHIVE gcc -v - ps: | # Install Rust Start-FileDownload "https://static.rust-lang.org/dist/rust-nightly-${env:TARGET}.exe" -FileName "rust-nightly.exe" @@ -29,8 +38,6 @@ install: # For -gnu builds if ($env:TARGET -match "-gnu$") { - $env:PATH="C:\msys64\usr\bin;$env:PATH" - $env:PATH="C:\msys64\mingw${env:BITS}\bin;$env:PATH" # Remove the mingw gcc to keep it from interfering with the build Remove-Item -Recurse -Force "C:\rust\lib\rustlib\$env:TARGET\bin\" }