From 17043bfe38f04a274c99b7c8d14c20f53f172629 Mon Sep 17 00:00:00 2001 From: Cyrix126 Date: Thu, 28 Mar 2024 22:34:11 +0100 Subject: [PATCH] feat: replace unstable http client hyper to reqwest using stable hyper --- Cargo.lock | 199 ++++++++++++++++++++++++++++++++++----- Cargo.toml | 3 +- src/components/node.rs | 47 ++++----- src/components/update.rs | 98 +++++++------------ src/helper/xmrig.rs | 64 +++++-------- src/helper/xvb.rs | 149 ++++++++++++----------------- 6 files changed, 316 insertions(+), 244 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0ebbb52..6f146ad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -664,6 +664,12 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + [[package]] name = "base64ct" version = "1.6.0" @@ -2078,8 +2084,6 @@ dependencies = [ "env_logger", "figment", "flate2", - "hyper", - "hyper-tls", "image 0.25.0", "is_elevated", "log", @@ -2090,6 +2094,7 @@ dependencies = [ "rand", "readable", "regex", + "reqwest", "rfd", "serde", "serde-this-or-that", @@ -2187,9 +2192,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.12" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ "bytes", "fnv", @@ -2198,12 +2203,24 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.6" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" dependencies = [ "bytes", "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", "pin-project-lite", ] @@ -2213,12 +2230,6 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" -[[package]] -name = "httpdate" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" - [[package]] name = "humantime" version = "2.1.0" @@ -2227,38 +2238,57 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.28" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +checksum = "186548d73ac615b32a73aafe38fb4f56c0d340e110e5a200bcadbaf2e199263a" dependencies = [ "bytes", "futures-channel", - "futures-core", "futures-util", "http", "http-body", "httparse", - "httpdate", "itoa", "pin-project-lite", - "socket2 0.5.6", + "smallvec", "tokio", - "tower-service", - "tracing", "want", ] [[package]] name = "hyper-tls" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ "bytes", + "http-body-util", "hyper", + "hyper-util", "native-tls", "tokio", "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "hyper", + "pin-project-lite", + "socket2 0.5.6", + "tokio", + "tower", + "tower-service", + "tracing", ] [[package]] @@ -2416,6 +2446,12 @@ dependencies = [ "libc", ] +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + [[package]] name = "is_elevated" version = "0.1.2" @@ -3248,6 +3284,26 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + [[package]] name = "pin-project-lite" version = "0.2.13" @@ -3345,7 +3401,7 @@ dependencies = [ "shared_library", "shell-words", "winapi", - "winreg", + "winreg 0.10.1", ] [[package]] @@ -3639,6 +3695,45 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" +[[package]] +name = "reqwest" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d66674f2b6fb864665eea7a3c1ac4e3dfacd2fda83cf6f935a612e01b0e3338" +dependencies = [ + "base64", + "bytes", + "futures-core", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-tls", + "hyper-util", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg 0.50.0", +] + [[package]] name = "rfd" version = "0.14.1" @@ -3719,6 +3814,15 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64", +] + [[package]] name = "rustversion" version = "1.0.14" @@ -3869,6 +3973,18 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + [[package]] name = "serial" version = "0.4.0" @@ -4151,6 +4267,12 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + [[package]] name = "sysinfo" version = "0.30.7" @@ -4420,6 +4542,28 @@ dependencies = [ "winnow 0.6.5", ] +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "pin-project", + "pin-project-lite", + "tokio", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + [[package]] name = "tower-service" version = "0.3.2" @@ -4432,6 +4576,7 @@ version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ + "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -5376,6 +5521,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + [[package]] name = "winres" version = "0.1.12" diff --git a/Cargo.toml b/Cargo.toml index a3ab5e4..b27ea14 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,8 +57,7 @@ egui_extras = { version = "0.27.0", features = ["image"] } #-------------------------------------------------------------------------------- env_logger = "0.11.3" figment = { version = "0.10.15", features = ["toml"] } -hyper = {version="0.14.28", features=["client", "http1"]} -hyper-tls = "0.5.0" +reqwest = {version = "0.12.2", default-features=false, features=["json", "default-tls"]} image = { version = "0.25.0", features = ["png"] } log = "0.4.21" num-format = { version = "0.4.4", default-features = false } diff --git a/src/components/node.rs b/src/components/node.rs index 60145a7..f5259c0 100644 --- a/src/components/node.rs +++ b/src/components/node.rs @@ -18,9 +18,9 @@ use crate::components::update::Pkg; use crate::{constants::*, macros::*}; use egui::Color32; -use hyper::{client::HttpConnector, Body, Client, Request}; use log::*; use rand::{thread_rng, Rng}; +use reqwest::{Client, RequestBuilder}; use std::sync::{Arc, Mutex}; use std::time::{Duration, Instant}; @@ -381,7 +381,7 @@ impl Ping { // Create HTTP client let info = "Creating HTTP Client".to_string(); lock!(ping).msg = info; - let client: Client = Client::builder().build(HttpConnector::new()); + let client = Client::new(); // Random User Agent let rand_user_agent = Pkg::get_user_agent(); @@ -393,16 +393,13 @@ impl Ping { let client = client.clone(); let ping = Arc::clone(&ping); let node_vec = Arc::clone(&node_vec); - let request = Request::builder() - .method("POST") - .uri("http://".to_string() + ip + ":" + rpc + "/json_rpc") + let request = client + .post("http://".to_string() + ip + ":" + rpc + "/json_rpc") .header("User-Agent", rand_user_agent) - .body(hyper::Body::from( - r#"{"jsonrpc":"2.0","id":"0","method":"get_info"}"#, - )) - .unwrap(); + .body(r#"{"jsonrpc":"2.0","id":"0","method":"get_info"}"#); + let handle = tokio::task::spawn(async move { - Self::response(client, request, ip, ping, percent, node_vec).await; + Self::response(request, ip, ping, percent, node_vec).await; }); handles.push(handle); } @@ -428,8 +425,7 @@ impl Ping { #[cold] #[inline(never)] async fn response( - client: Client, - request: Request, + request: RequestBuilder, ip: &'static str, ping: Arc>, percent: f32, @@ -438,10 +434,10 @@ impl Ping { let ms; let now = Instant::now(); - match tokio::time::timeout(Duration::from_secs(5), client.request(request)).await { + match tokio::time::timeout(Duration::from_secs(5), request.send()).await { Ok(Ok(json_rpc)) => { // Attempt to convert to JSON-RPC. - match hyper::body::to_bytes(json_rpc.into_body()).await { + match json_rpc.bytes().await { Ok(b) => match serde_json::from_slice::>(&b) { Ok(rpc) => { if rpc.result.mainnet && rpc.result.synchronized { @@ -485,6 +481,8 @@ impl Ping { //---------------------------------------------------------------------------------------------------- NODE #[cfg(test)] mod test { + use reqwest::Client; + use crate::components::node::{ format_ip, REMOTE_NODES, REMOTE_NODE_LENGTH, REMOTE_NODE_MAX_CHARS, }; @@ -514,7 +512,6 @@ mod test { #[tokio::test] #[ignore] async fn full_ping() { - use hyper::{client::HttpConnector, Client, Request}; use serde::{Deserialize, Serialize}; #[derive(Deserialize, Serialize)] @@ -524,7 +521,7 @@ mod test { } // Create HTTP client - let client: Client = Client::builder().build(HttpConnector::new()); + let client = Client::new(); // Random User Agent let rand_user_agent = Pkg::get_user_agent(); @@ -541,16 +538,13 @@ mod test { let client = client.clone(); // Try 3 times before failure let mut i = 1; - let mut response = loop { - let request = Request::builder() - .method("POST") - .uri("http://".to_string() + ip + ":" + rpc + "/json_rpc") + let response = loop { + let request = client + .post("http://".to_string() + ip + ":" + rpc + "/json_rpc") .header("User-Agent", rand_user_agent) - .body(hyper::Body::from( - r#"{"jsonrpc":"2.0","id":"0","method":"get_info"}"#, - )) - .unwrap(); - match client.request(request).await { + .body(r#"{"jsonrpc":"2.0","id":"0","method":"get_info"}"#); + + match request.send().await { Ok(response) => break response, Err(e) => { println!("{:#?}", e); @@ -565,8 +559,7 @@ mod test { } } }; - let body = hyper::body::to_bytes(response.body_mut()).await.unwrap(); - let getinfo: GetInfo = serde_json::from_slice(&body).unwrap(); + let getinfo = response.json::().await.unwrap(); assert!(getinfo.id == "0"); assert!(getinfo.jsonrpc == "2.0"); n += 1; diff --git a/src/components/update.rs b/src/components/update.rs index 36b8d44..0835386 100644 --- a/src/components/update.rs +++ b/src/components/update.rs @@ -37,13 +37,12 @@ use crate::{ utils::errors::{ErrorButtons, ErrorFerris, ErrorState}, }; use anyhow::{anyhow, Error}; -use hyper::{ - header::{HeaderValue, LOCATION}, - Body, Client, Request, -}; +use bytes::Bytes; use log::*; use rand::distributions::Alphanumeric; use rand::{thread_rng, Rng}; +use reqwest::header::{LOCATION, USER_AGENT}; +use reqwest::{Client, RequestBuilder}; use serde::{Deserialize, Serialize}; use std::path::{Path, PathBuf}; use std::sync::{Arc, Mutex}; @@ -322,8 +321,8 @@ impl Update { Ok(tmp_dir) } - #[cold] - #[inline(never)] + // #[cold] + // #[inline(never)] // Get an HTTPS client. Uses [Arti] if Tor is enabled. // The base type looks something like [hyper::Client<...>]. // This is then wrapped with the custom [ClientEnum] type to implement @@ -337,13 +336,6 @@ impl Update { // ClientEnum::Tor(T) => get_response(... T ...) // ClientEnum::Https(H) => get_response(... H ...) // - pub fn get_client() -> Result { - let mut connector = hyper_tls::HttpsConnector::new(); - connector.https_only(true); - let client = ClientEnum::Https(Client::builder().build(connector)); - Ok(client) - } - #[cold] #[inline(never)] // Intermediate function that spawns a new thread @@ -553,7 +545,7 @@ impl Update { info!("Update | {}", msg); *lock!(lock.msg) = msg; drop(lock); - let client = Self::get_client()?; + let client = Client::new(); *lock2!(update, prog) += 5.0; info!("Update | Init ... OK ... {}%", lock2!(update, prog)); @@ -584,11 +576,7 @@ impl Update { let link = pkg.link_metadata.to_string(); // Send to async let handle: JoinHandle> = tokio::spawn(async move { - match client { - ClientEnum::Https(h) => { - Pkg::get_metadata(new_ver, h, link, user_agent).await - } - } + Pkg::get_metadata(new_ver, &client, link, user_agent).await }); handles.push(handle); } @@ -726,11 +714,10 @@ impl Update { } }; info!("Update | {} ... {}", pkg.name, link); - let handle: JoinHandle> = tokio::spawn(async move { - match client { - ClientEnum::Https(h) => Pkg::get_bytes(bytes, h, link, user_agent).await, - } - }); + let handle: JoinHandle> = + tokio::spawn( + async move { Pkg::get_bytes(bytes, &client, link, user_agent).await }, + ); handles.push(handle); } // Handle await @@ -906,11 +893,6 @@ impl Update { } } -#[derive(Debug, Clone)] -pub enum ClientEnum { - Https(hyper::Client>), -} - //---------------------------------------------------------------------------------------------------- Pkg struct/impl #[derive(Debug, Clone)] pub struct Pkg { @@ -919,7 +901,7 @@ pub struct Pkg { link_prefix: &'static str, link_suffix: &'static str, link_extension: &'static str, - bytes: Arc>, + bytes: Arc>, new_ver: Arc>, } @@ -974,35 +956,28 @@ impl Pkg { #[cold] #[inline(never)] // Generate GET request based off input URI + fake user agent - fn get_request(link: String, user_agent: &'static str) -> Result, anyhow::Error> { - let request = Request::builder() - .method("GET") - .uri(link) - .header( - hyper::header::USER_AGENT, - HeaderValue::from_static(user_agent), - ) - .body(Body::empty())?; - Ok(request) + fn get_request( + client: &Client, + link: String, + user_agent: &'static str, + ) -> Result { + Ok(client.get(link).header(USER_AGENT, user_agent)) } #[cold] #[inline(never)] // Get metadata using [Generic hyper::client] & [Request] // and change [version, prog] under an Arc - async fn get_metadata( + async fn get_metadata( new_ver: Arc>, - client: Client, + client: &Client, link: String, user_agent: &'static str, - ) -> Result<(), Error> - where - C: hyper::client::connect::Connect + Clone + Send + Sync + 'static, - { - let request = Pkg::get_request(link, user_agent)?; - let mut response = client.request(request).await?; - let body = hyper::body::to_bytes(response.body_mut()).await?; - let body: TagName = serde_json::from_slice(&body)?; + ) -> Result<(), Error> { + let request = Pkg::get_request(&client, link, user_agent)?; + let response = request.send().await?; + dbg!(&response); + let body = response.json::().await?; *lock!(new_ver) = body.tag_name; Ok(()) } @@ -1011,22 +986,20 @@ impl Pkg { #[inline(never)] // Takes a [Request], fills the appropriate [Pkg] // [bytes] field with the [Archive/Standalone] - async fn get_bytes( + async fn get_bytes( bytes: Arc>, - client: Client, + client: &Client, link: String, user_agent: &'static str, - ) -> Result<(), anyhow::Error> - where - C: hyper::client::connect::Connect + Clone + Send + Sync + 'static, - { - let request = Self::get_request(link, user_agent)?; - let mut response = client.request(request).await?; + ) -> Result<(), anyhow::Error> { + let request = Self::get_request(&client, link, user_agent)?; + let mut response = request.send().await?; // GitHub sends a 302 redirect, so we must follow // the [Location] header... only if Reqwest had custom // connectors so I didn't have to manually do this... if response.headers().contains_key(LOCATION) { - let request = Self::get_request( + response = Self::get_request( + &client, response .headers() .get(LOCATION) @@ -1034,10 +1007,11 @@ impl Pkg { .to_str()? .to_string(), user_agent, - )?; - response = client.request(request).await?; + )? + .send() + .await?; } - let body = hyper::body::to_bytes(response.into_body()).await?; + let body = response.bytes().await?; *lock!(bytes) = body; Ok(()) } diff --git a/src/helper/xmrig.rs b/src/helper/xmrig.rs index cd9418b..d162fb5 100644 --- a/src/helper/xmrig.rs +++ b/src/helper/xmrig.rs @@ -7,6 +7,8 @@ use anyhow::{anyhow, Result}; use log::*; use readable::num::Unsigned; use readable::up::Uptime; +use reqwest::header::AUTHORIZATION; +use reqwest::Client; use serde::{Deserialize, Serialize}; use serde_json::Value; use std::path::Path; @@ -444,8 +446,7 @@ impl Helper { let output_parse = Arc::clone(&lock!(process).output_parse); let output_pub = Arc::clone(&lock!(process).output_pub); - let client: hyper::Client = - hyper::Client::builder().build(hyper::client::HttpConnector::new()); + let client = Client::new(); let start = lock!(process).start; let api_uri = { if !api_ip_port.ends_with('/') { @@ -617,7 +618,7 @@ impl Helper { ); // Send an HTTP API request debug!("XMRig Watchdog | Attempting HTTP API request..."); - match PrivXmrigApi::request_xmrig_api(client.clone(), &api_uri, token).await { + match PrivXmrigApi::request_xmrig_api(&client, &api_uri, token).await { Ok(priv_api) => { debug!("XMRig Watchdog | HTTP API request OK, attempting [update_from_priv()]"); PubXmrigApi::update_from_priv(&pub_api, priv_api); @@ -809,27 +810,22 @@ impl PrivXmrigApi { #[inline] // Send an HTTP request to XMRig's API, serialize it into [Self] and return it async fn request_xmrig_api( - client: hyper::Client, + client: &Client, api_uri: &str, token: &str, ) -> std::result::Result { - let request = hyper::Request::builder() - .method("GET") - .header("Authorization", ["Bearer ", token].concat()) - .uri(api_uri) - .body(hyper::Body::empty())?; - let response = tokio::time::timeout( - std::time::Duration::from_millis(5000), - client.request(request), - ) - .await?; - let body = hyper::body::to_bytes(response?.body_mut()).await?; - Ok(serde_json::from_slice::(&body)?) + let request = client + .get(api_uri) + .header(AUTHORIZATION, ["Bearer ", token].concat()); + Ok(request + .timeout(std::time::Duration::from_millis(5000)) + .send() + .await?.json().await?) } #[inline] // // Replace config with new node pub async fn update_xmrig_config( - client: &hyper::Client, + client: &Client, api_uri: &str, token: &str, node: &XvbNode, @@ -837,19 +833,10 @@ impl PrivXmrigApi { gui_api_xmrig: &Arc>, ) -> Result<()> { // get config - let request = hyper::Request::builder() - .method("GET") - .header("Authorization", ["Bearer ", token].concat()) - .uri(api_uri) - .body(hyper::Body::empty())?; - let response = tokio::time::timeout( - std::time::Duration::from_millis(500), - client.request(request), - ) - .await?; - let body = hyper::body::to_bytes(response?.body_mut()).await?; - // deserialize to json - let mut config = serde_json::from_slice::(&body)?; + let request = client + .get(api_uri) + .header(AUTHORIZATION, ["Bearer ", token].concat()); + let mut config = request.send().await?.json::().await?; // modify node configuration let uri = [node.url(), ":".to_string(), node.port()].concat(); info!("replace xmrig config with node {}", uri); @@ -868,20 +855,15 @@ impl PrivXmrigApi { .pointer_mut("/pools/0/keepalive") .ok_or_else(|| anyhow!("pools/0/keepalive does not exist in xmrig config"))? = node.keepalive().into(); - // reconstruct body from new config - let body = hyper::body::Body::from(config.to_string()); // send new config - let request = hyper::Request::builder() - .method("PUT") + client + .put(api_uri) .header("Authorization", ["Bearer ", token].concat()) .header("Content-Type", "application/json") - .uri(api_uri) - .body(body)?; - tokio::time::timeout( - std::time::Duration::from_millis(500), - client.request(request), - ) - .await??; + .timeout(std::time::Duration::from_secs(5)) + .body(config.to_string()) + .send() + .await?; // update process status lock!(gui_api_xmrig).node = node.to_string(); anyhow::Ok(()) diff --git a/src/helper/xvb.rs b/src/helper/xvb.rs index a24003b..9b57686 100644 --- a/src/helper/xvb.rs +++ b/src/helper/xvb.rs @@ -1,12 +1,9 @@ use anyhow::{bail, Result}; -use bytes::Bytes; use derive_more::Display; -use hyper::client::HttpConnector; -use hyper::{Client, Request, StatusCode}; -use hyper_tls::HttpsConnector; use log::{debug, error, info, warn}; use readable::num::Float; use readable::up::Uptime; +use reqwest::{Client, StatusCode}; use serde::Deserialize; use std::collections::VecDeque; use std::fmt::Write; @@ -137,14 +134,10 @@ impl Helper { process_xmrig: Arc>, ) { // client for http and one for https, both will be valid for the thread scope. - let https = HttpsConnector::new(); - let client_https = hyper::Client::builder().build(https); - // client http should be created only if process completely started, because it's not useful otherwise, but it would possibly be unitiliazed. - let client_http = - Arc::new(hyper::Client::builder().build(hyper::client::HttpConnector::new())); + let client = reqwest::Client::new(); info!("XvB | verify address and token"); if let Err(err) = - XvbPrivStats::request_api(&client_https, &state_p2pool.address, &state_xvb.token).await + XvbPrivStats::request_api(&client, &state_p2pool.address, &state_xvb.token).await { // send to console: token non existent for address on XvB server warn!("Xvb | Start ... Partially failed because token and associated address are not existent on XvB server: {}\n", err); @@ -183,13 +176,12 @@ impl Helper { lock!(process).state = ProcessState::Alive; let pub_api_c = pub_api.clone(); - let client_http_c = client_http.clone(); + let client = client.clone(); let process_c = process.clone(); let gui_api_c = gui_api.clone(); // will check which pool to use, will send NotMining if spawn(async move { - XvbNode::update_fastest_node(&client_http_c, &pub_api_c, &gui_api_c, &process_c) - .await; + XvbNode::update_fastest_node(&client, &pub_api_c, &gui_api_c, &process_c).await; }); } // let mut old_shares = 0; @@ -240,7 +232,7 @@ impl Helper { if signal_interrupt( process.clone(), start.into(), - &client_http, + &client, &pub_api, &gui_api, &gui_api_xmrig, @@ -255,14 +247,14 @@ impl Helper { // do not wait for the request to finish so that they are retrieved at exactly one minute interval. // Private API will also use this instant if XvB is Alive. last_request = tokio::time::Instant::now(); - let client_https_c = client_https.clone(); + let client_c = client.clone(); let pub_api_c = pub_api.clone(); let gui_api_c = gui_api.clone(); let process_c = process.clone(); // will send a stop signal if it failed or update data with new one. spawn(async move { debug!("XvB Watchdog | Attempting HTTP public API request..."); - match XvbPubStats::request_api(&client_https_c).await { + match XvbPubStats::request_api(&client_c).await { Ok(new_data) => { debug!("XvB Watchdog | HTTP API request OK"); lock!(&pub_api_c).stats_pub = new_data; @@ -289,7 +281,7 @@ impl Helper { if lock!(process).state == ProcessState::Alive { debug!("XvB Watchdog | Attempting HTTP private API request..."); // reload private stats, send signal if error - let client_https_c = client_https.clone(); + let client_https_c = client.clone(); let pub_api_c = pub_api.clone(); let gui_api_c = gui_api.clone(); let process_c = process.clone(); @@ -297,21 +289,9 @@ impl Helper { let token = state_xvb.token.clone(); spawn(async move { match XvbPrivStats::request_api(&client_https_c, &address, &token).await { - Ok(b) => { + Ok(new_data) => { debug!("XvB Watchdog | HTTP API request OK"); - let new_data = match serde_json::from_slice::(&b) { - Ok(data) => Some(data), - Err(e) => { - warn!("XvB Watchdog | Data provided from private API is not deserializ-able.Error: {}", e); - output_console(&gui_api_c, &format!("XvB Watchdog | Data provided from private API is not deserializ-able.Error: {}", e)); - lock!(process_c).state = ProcessState::Failed; - lock!(process_c).signal = ProcessSignal::Stop; - None - } - }; - if let Some(new_data) = new_data { - lock!(&pub_api_c).stats_priv = new_data; - } + lock!(&pub_api_c).stats_priv = new_data; } Err(err) => { warn!( @@ -358,7 +338,7 @@ impl Helper { // the time that takes the algorithm do decide the next ten minutes could means less p2pool mining. It is solved by the buffer and spawning requests. last_algorithm = tokio::time::Instant::now(); // request XMrig to mine on P2pool - let client_http_c = client_http.clone(); + let client_http_c = client.clone(); let gui_api_c = gui_api.clone(); let token_xmrig = Arc::new(state_xmrig.token.clone()); let token_xmrig_c = token_xmrig.clone(); @@ -443,7 +423,7 @@ impl Helper { // sleep 10m less spared time then request XMrig to mine on XvB let was_instant = last_algorithm; let gui_api_c = gui_api.clone(); - let client_http_c = client_http.clone(); + let client_http_c = client.clone(); let gui_api_xmrig_c = gui_api_xmrig.clone(); spawn(async move { Helper::sleep_then_update_node_xmrig( @@ -541,7 +521,7 @@ impl Helper { async fn sleep_then_update_node_xmrig( was_instant: &tokio::time::Instant, spared_time: u32, - client: &Client, + client: &Client, api_uri: &str, token_xmrig: &str, address: &str, @@ -651,50 +631,45 @@ pub struct XvbPrivStats { impl XvbPubStats { #[inline] // Send an HTTP request to XvB's API, serialize it into [Self] and return it - async fn request_api( - client: &hyper::Client>, - ) -> std::result::Result { - let request = hyper::Request::builder() - .method("GET") - .uri(XVB_URL_PUBLIC_API) - .body(hyper::Body::empty())?; - let response = - tokio::time::timeout(std::time::Duration::from_secs(10), client.request(request)) - .await?; - // let response = client.request(request).await; - - let body = hyper::body::to_bytes(response?.body_mut()).await?; - Ok(serde_json::from_slice::(&body)?) + async fn request_api(client: &Client) -> std::result::Result { + Ok(client + .get(XVB_URL_PUBLIC_API) + .send() + .await? + .json::() + .await?) } } impl XvbPrivStats { - pub async fn request_api( - client: &hyper::Client>, - address: &str, - token: &str, - ) -> Result { - if let Ok(request) = hyper::Request::builder() - .method("GET") - .uri(format!( - "{}/cgi-bin/p2pool_bonus_history_api.cgi?address={}&token={}", - XVB_URL, address, token - )) - .body(hyper::Body::empty()) - { - match client.request(request).await { - Ok(mut resp) => match resp.status() { - StatusCode::OK => Ok(hyper::body::to_bytes(resp.body_mut()).await?), - StatusCode::UNPROCESSABLE_ENTITY => { - bail!("the token is invalid for this xmr address.") - } - _ => bail!("The status of the response is not expected"), - }, + pub async fn request_api(client: &Client, address: &str, token: &str) -> Result { + let resp = client + .get( + [ + XVB_URL, + "/cgi-bin/p2pool_bonus_history_api.cgi?address=", + address, + "&token=", + token, + ] + .concat(), + ) + .send() + .await?; + match resp.status() { + StatusCode::OK => match resp.json::().await { + Ok(s) => Ok(s), Err(err) => { - bail!("error from response: {}", err) + error!("XvB Watchdog | Data provided from private API is not deserializ-able.Error: {}", err); + bail!( + "Data provided from private API is not deserializ-able.Error: {}", + err + ); } + }, + StatusCode::UNPROCESSABLE_ENTITY => { + bail!("the token is invalid for this xmr address.") } - } else { - bail!("request could not be build") + _ => bail!("The status of the response is not expected"), } } fn calcul_donated_time( @@ -837,7 +812,7 @@ impl XvbNode { } pub async fn update_fastest_node( - client: &Arc>, + client: &Client, pub_api_xvb: &Arc>, gui_api_xvb: &Arc>, process_xvb: &Arc>, @@ -893,20 +868,16 @@ impl XvbNode { } lock!(pub_api_xvb).stats_priv.node = node; } - async fn ping(ip: &str, client: &Client) -> u128 { - let request = Request::builder() - .method("POST") - .uri("http://".to_string() + ip + ":" + XVB_NODE_RPC + "/json_rpc") - .body(hyper::Body::from( - r#"{"jsonrpc":"2.0","id":"0","method":"get_info"}"#, - )) - .expect("hyper request should build."); + async fn ping(ip: &str, client: &Client) -> u128 { + let request = client + .post("http://".to_string() + ip + ":" + XVB_NODE_RPC + "/json_rpc") + .body(r#"{"jsonrpc":"2.0","id":"0","method":"get_info"}"#); let ms; let now = Instant::now(); - match tokio::time::timeout(Duration::from_secs(8), client.request(request)).await { + match tokio::time::timeout(Duration::from_secs(8), request.send()).await { Ok(Ok(json_rpc)) => { // Attempt to convert to JSON-RPC. - match hyper::body::to_bytes(json_rpc.into_body()).await { + match json_rpc.bytes().await { Ok(b) => match serde_json::from_slice::>(&b) { Ok(rpc) => { if rpc.result.mainnet && rpc.result.synchronized { @@ -958,7 +929,7 @@ impl PubXvbApi { fn signal_interrupt( process: Arc>, start: Instant, - client_http: &Arc>, + client_http: &Client, pub_api: &Arc>, gui_api: &Arc>, gui_api_xmrig: &Arc>, @@ -1081,18 +1052,16 @@ mod test { }; use super::{PubXvbApi, XvbPrivStats, XvbPubStats}; - use hyper::Client; - use hyper_tls::HttpsConnector; + use reqwest::Client; #[test] fn public_api_deserialize() { - let https = HttpsConnector::new(); - let client = hyper::Client::builder().build(https); - let new_data = thread::spawn(move || corr(client)).join().unwrap(); + let client = Client::new(); + let new_data = thread::spawn(move || corr(&client)).join().unwrap(); assert!(!new_data.reward_yearly.is_empty()); } #[tokio::main] - async fn corr(client: Client>) -> XvbPubStats { + async fn corr(client: &Client) -> XvbPubStats { XvbPubStats::request_api(&client).await.unwrap() } #[test]