From 33856b04f27284b22ae74c31ca0c3f80458da7ae Mon Sep 17 00:00:00 2001 From: Muhammad Hamza Date: Tue, 30 May 2023 18:19:26 +0500 Subject: [PATCH] Replace curl with ureq The HTTP client is now pure Rust --- .gitignore | 2 + Cargo.lock | 150 ++++++++++++++++++++++------- Cargo.toml | 15 +-- src/install/krate.rs | 15 ++- src/lib.rs | 1 - src/manifest/mod.rs | 42 +++----- src/test/webdriver.rs | 15 --- src/test/webdriver/chromedriver.rs | 19 ++-- src/test/webdriver/geckodriver.rs | 46 +++------ 9 files changed, 159 insertions(+), 146 deletions(-) diff --git a/.gitignore b/.gitignore index 4d85744..b0b6ed3 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,5 @@ tests/bin /build-installer docs/book docs/installer + +.idea diff --git a/Cargo.lock b/Cargo.lock index d9bc197..4661047 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -160,9 +160,15 @@ dependencies = [ [[package]] name = "base64" -version = "0.21.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.21.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" [[package]] name = "base64ct" @@ -814,9 +820,9 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "h2" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17f8a914c2987b688368b5138aa05321db91f4090cf26118185672ad588bce21" +checksum = "d357c7ae988e7d2182f7d7871d0b963962420b0678b0997ce7de72001aeab782" dependencies = [ "bytes", "fnv", @@ -1186,14 +1192,13 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" +checksum = "eebffdb73fe72e917997fad08bdbf31ac50b0fa91cec93e69a0662e4264d454c" dependencies = [ "libc", - "log", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] @@ -1272,9 +1277,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "openssl" -version = "0.10.52" +version = "0.10.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01b8574602df80f7b85fdfc5392fa884a4e3b3f4f35402c070ab34c3d3f78d56" +checksum = "12df40a956736488b7b44fe79fe12d4f245bb5b3f5a1f6095e499760015be392" dependencies = [ "bitflags", "cfg-if", @@ -1302,24 +1307,14 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" -[[package]] -name = "openssl-src" -version = "111.25.3+1.1.1t" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "924757a6a226bf60da5f7dd0311a34d2b52283dd82ddeb103208ddc66362f80c" -dependencies = [ - "cc", -] - [[package]] name = "openssl-sys" -version = "0.9.87" +version = "0.9.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e17f59264b2809d77ae94f0e1ebabc434773f370d6ca667bd223ea10e06cc7e" +checksum = "c2ce0f250f34a308dcfdbb351f511359857d4ed2134ba715a4eadd46e1ffd617" dependencies = [ "cc", "libc", - "openssl-src", "pkg-config", "vcpkg", ] @@ -1549,11 +1544,11 @@ checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c" [[package]] name = "reqwest" -version = "0.11.17" +version = "0.11.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13293b639a097af28fc8a90f22add145a9c954e49d77da06263d58cf44d5fb91" +checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" dependencies = [ - "base64", + "base64 0.21.2", "bytes", "encoding_rs", "futures-core", @@ -1584,6 +1579,21 @@ dependencies = [ "winreg", ] +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin", + "untrusted", + "web-sys", + "winapi", +] + [[package]] name = "rustc-demangle" version = "0.1.23" @@ -1604,6 +1614,18 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "rustls" +version = "0.20.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f" +dependencies = [ + "log", + "ring", + "sct", + "webpki", +] + [[package]] name = "ryu" version = "1.0.13" @@ -1640,11 +1662,21 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1" +[[package]] +name = "sct" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "security-framework" -version = "2.8.2" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a332be01508d814fed64bf28f798a146d73792121129962fdf335bb3c49a4254" +checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8" dependencies = [ "bitflags", "core-foundation", @@ -1655,9 +1687,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31c9bb296072e961fcbd8853511dd39c2d8be2deb1e17c6860b1d30732b323b4" +checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7" dependencies = [ "core-foundation-sys", "libc", @@ -1817,6 +1849,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + [[package]] name = "strsim" version = "0.8.0" @@ -1993,9 +2031,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.28.1" +version = "1.28.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0aa32867d44e6f2ce3385e89dceb990188b8bb0fb25b0cf576647a6f98ac5105" +checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2" dependencies = [ "autocfg", "bytes", @@ -2093,9 +2131,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.30" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" dependencies = [ "once_cell", ] @@ -2145,6 +2183,30 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "ureq" +version = "2.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "338b31dd1314f68f3aabf3ed57ab922df95ffcd902476ca7ba3c4ce7b908c46d" +dependencies = [ + "base64 0.13.1", + "flate2", + "log", + "once_cell", + "rustls", + "serde", + "serde_json", + "url", + "webpki", + "webpki-roots", +] + [[package]] name = "url" version = "2.3.1" @@ -2307,14 +2369,12 @@ dependencies = [ "cargo_metadata", "chrono", "console", - "curl", "dialoguer", "env_logger", "glob", "human-panic", "lazy_static", "log", - "openssl", "parking_lot", "predicates 2.1.5", "reqwest", @@ -2329,6 +2389,7 @@ dependencies = [ "structopt", "tempfile", "toml 0.5.11", + "ureq", "walkdir", "which", ] @@ -2343,6 +2404,25 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpki" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "webpki-roots" +version = "0.22.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" +dependencies = [ + "webpki", +] + [[package]] name = "which" version = "4.4.0" diff --git a/Cargo.toml b/Cargo.toml index e7b6b55..8044ac0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,15 +17,12 @@ binary-install = "0.1.0" cargo_metadata = "0.15.2" chrono = "0.4.23" console = "0.15.5" -curl = "0.4.44" dialoguer = "0.10.3" env_logger = { version = "0.10.0", default-features = false } glob = "0.3.1" human-panic = "1.0.3" log = "0.4.17" -openssl = { version = '0.10.48', optional = true } parking_lot = "0.12.1" -reqwest = { version = "0.11.14", features = ["blocking"] } semver = "1.0.16" serde = "1.0.152" serde_derive = "1.0.152" @@ -35,6 +32,7 @@ siphasher = "0.3.10" strsim = "0.10.0" structopt = "0.3.26" toml = "0.5.11" +ureq = { version = "2.6.2", features = ["json"] } walkdir = "2.3.2" which = "4.4.0" @@ -44,14 +42,5 @@ lazy_static = "1.4.0" predicates = "2.1.5" serial_test = "1.0.0" tempfile = "3.3.0" +reqwest = { version = "0.11.14", features = ["blocking"] } -[features] -# OpenSSL is vendored by default, can use system OpenSSL through feature flag. -default = ['openssl/vendored'] - -# Treat compiler warnings as a build error. -# This only runs in CI by default -strict = ['openssl/vendored'] -sys-openssl = ['openssl'] -# Keeping feature for users already using this feature flag -vendored-openssl = ['openssl/vendored'] diff --git a/src/install/krate.rs b/src/install/krate.rs index 6fc44a7..62b4474 100644 --- a/src/install/krate.rs +++ b/src/install/krate.rs @@ -1,6 +1,5 @@ use crate::install::Tool; use anyhow::Result; -use reqwest::header::USER_AGENT; use serde::Deserialize; const VERSION: Option<&str> = option_env!("CARGO_PKG_VERSION"); @@ -18,16 +17,14 @@ pub struct KrateResponse { impl Krate { pub fn new(name: &Tool) -> Result { let krate_address = format!("https://crates.io/api/v1/crates/{}", name); - let client = reqwest::blocking::Client::new(); - let res = client - .get(&krate_address) - .header( - USER_AGENT, - format!("wasm-pack/{}", VERSION.unwrap_or("unknown")), + let res = ureq::get(&krate_address) + .set( + "user-agent", + &format!("wasm-pack/{}", VERSION.unwrap_or("unknown")), ) - .send()?; + .call()?; - let kr: KrateResponse = serde_json::from_str(&res.text()?)?; + let kr: KrateResponse = res.into_json()?; Ok(kr.krate) } } diff --git a/src/lib.rs b/src/lib.rs index 8410b48..1f5c508 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,7 +19,6 @@ extern crate serde_json; extern crate structopt; extern crate binary_install; extern crate chrono; -extern crate curl; extern crate dialoguer; extern crate log; extern crate toml; diff --git a/src/manifest/mod.rs b/src/manifest/mod.rs index 54f7740..26c28e4 100644 --- a/src/manifest/mod.rs +++ b/src/manifest/mod.rs @@ -20,7 +20,6 @@ use crate::PBAR; use cargo_metadata::Metadata; use chrono::offset; use chrono::DateTime; -use curl::easy; use serde::{self, Deserialize}; use serde_json; use std::collections::BTreeSet; @@ -120,15 +119,6 @@ struct CargoWasmPackProfileWasmBindgen { dwarf_debug_info: Option, } -struct Collector(Vec); - -impl easy::Handler for Collector { - fn write(&mut self, data: &[u8]) -> Result { - self.0.extend_from_slice(data); - Ok(data.len()) - } -} - /// Struct for storing information received from crates.io #[derive(Deserialize, Debug)] pub struct Crate { @@ -233,26 +223,24 @@ impl Crate { /// Call to the crates.io api and return the latest version of `wasm-pack` fn check_wasm_pack_latest_version() -> Result { let url = "https://crates.io/api/v1/crates/wasm-pack"; - - let mut easy = easy::Easy2::new(Collector(Vec::new())); - - easy.useragent(&format!( - "wasm-pack/{} ({})", - WASM_PACK_VERSION.unwrap_or_else(|| "unknown"), - WASM_PACK_REPO_URL - ))?; - - easy.url(url)?; - easy.get(true)?; - easy.perform()?; - - let status_code = easy.response_code()?; + let agent = ureq::builder() + .user_agent(&format!( + "wasm-pack/{} ({})", + WASM_PACK_VERSION.unwrap_or_else(|| "unknown"), + WASM_PACK_REPO_URL + )) + .build(); + let resp = agent + .get(url) + .call() + .context("failed to get wasm-pack version")?; + + let status_code = resp.status(); if 200 <= status_code && status_code < 300 { - let contents = easy.get_ref(); - let result = String::from_utf8_lossy(&contents.0); + let json = resp.into_json()?; - Ok(serde_json::from_str(result.into_owned().as_str())?) + Ok(json) } else { bail!( "Received a bad HTTP status code ({}) when checking for newer wasm-pack version at: {}", diff --git a/src/test/webdriver.rs b/src/test/webdriver.rs index fe77bfd..2299f8f 100644 --- a/src/test/webdriver.rs +++ b/src/test/webdriver.rs @@ -34,18 +34,3 @@ fn get_and_notify( None => Ok(None), } } - -struct Collector(Vec); - -impl Collector { - pub fn take_content(&mut self) -> Vec { - std::mem::take(&mut self.0) - } -} - -impl curl::easy::Handler for Collector { - fn write(&mut self, data: &[u8]) -> Result { - self.0.extend_from_slice(data); - Ok(data.len()) - } -} diff --git a/src/test/webdriver/chromedriver.rs b/src/test/webdriver/chromedriver.rs index 7160364..5aa123e 100644 --- a/src/test/webdriver/chromedriver.rs +++ b/src/test/webdriver/chromedriver.rs @@ -1,4 +1,4 @@ -use super::{get_and_notify, Collector}; +use super::get_and_notify; use crate::install::InstallMode; use crate::stamps; use crate::target; @@ -117,17 +117,12 @@ fn should_load_chromedriver_version_from_stamp(json: &serde_json::Value) -> bool } fn fetch_chromedriver_version() -> Result { - let mut handle = curl::easy::Easy2::new(Collector(Vec::new())); - handle - .url("https://chromedriver.storage.googleapis.com/LATEST_RELEASE") - .context("URL to fetch chromedriver's LATEST_RELEASE is invalid")?; - handle - .perform() - .context("fetching of chromedriver's LATEST_RELEASE failed")?; - - let content = handle.get_mut().take_content(); - let version = - String::from_utf8(content).context("chromedriver's LATEST_RELEASE is not valid UTF-8")?; + let version = ureq::get("https://chromedriver.storage.googleapis.com/LATEST_RELEASE") + .call() + .context("fetching of chromedriver's LATEST_RELEASE failed")? + .into_string() + .context("converting chromedriver version response to string failed")?; + Ok(version) } diff --git a/src/test/webdriver/geckodriver.rs b/src/test/webdriver/geckodriver.rs index 7faf1e9..8342d49 100644 --- a/src/test/webdriver/geckodriver.rs +++ b/src/test/webdriver/geckodriver.rs @@ -1,4 +1,4 @@ -use super::{get_and_notify, Collector}; +use super::get_and_notify; use crate::install::InstallMode; use crate::stamps; use crate::target; @@ -77,11 +77,8 @@ pub fn install_geckodriver(cache: &Cache, installation_allowed: bool) -> Result< /// - it should be relatively safe because each `geckodriver` supports many `Firefox` versions: /// https://firefox-source-docs.mozilla.org/testing/geckodriver/Support.html#supported-platforms fn get_geckodriver_url(target: &str, ext: &str) -> String { - let fetch_and_save_version = || { - fetch_latest_geckodriver_tag_json() - .and_then(get_version_from_json) - .and_then(save_geckodriver_version) - }; + let fetch_and_save_version = + || fetch_latest_geckodriver_tag_json().and_then(save_geckodriver_version); let geckodriver_version = if target::WINDOWS { log::info!( @@ -142,37 +139,18 @@ fn should_load_geckodriver_version_from_stamp(json: &serde_json::Value) -> bool } fn fetch_latest_geckodriver_tag_json() -> Result { - let mut headers = curl::easy::List::new(); - headers - .append("Accept: application/json") - .context("cannot fetch geckodriver's latest release data - appending header failed")?; - - let mut handle = curl::easy::Easy2::new(Collector(Vec::new())); - handle - .url("https://github.com/mozilla/geckodriver/releases/latest") - .context("URL to fetch geckodriver's latest release data is invalid")?; - handle - .http_headers(headers) - .context("cannot fetch geckodriver's latest release data - setting headers failed")?; - // We will be redirected from the `latest` placeholder to the specific tag name. - handle - .follow_location(true) - .context("cannot fetch geckodriver's latest release data - enabling redirects failed")?; - handle - .perform() - .context("fetching of geckodriver's latest release data failed")?; - - let content = handle.get_mut().take_content(); - let version = String::from_utf8(content) - .context("geckodriver's latest release data is not valid UTF-8")?; - - Ok(version) + let content: serde_json::Value = + ureq::get("https://github.com/mozilla/geckodriver/releases/latest") + .set("Accept", "application/json") + .call() + .context("fetching of geckodriver's latest release data failed")? + .into_json()?; + + get_version_from_json(content) } /// JSON example: `{"id":15227534,"tag_name":"v0.24.0","update_url":"/mozzila...` -fn get_version_from_json(json: impl AsRef) -> Result { - let json: serde_json::Value = serde_json::from_str(json.as_ref()) - .context("geckodriver's latest release data is not valid JSON")?; +fn get_version_from_json(json: serde_json::Value) -> Result { json.get("tag_name") .and_then(|tag_name| tag_name.as_str().map(ToOwned::to_owned)) .ok_or_else(|| anyhow!("cannot get `tag_name` from geckodriver's latest release data"))