From cb5bb685d8e82ab8d667015c615fa87dccefd04b Mon Sep 17 00:00:00 2001 From: Jose Celano Date: Tue, 30 Jan 2024 14:03:07 +0000 Subject: [PATCH] feat: [#640] Tracker Chekcer: announce check --- src/console/clients/checker/service.rs | 68 +++++++++++++++++++------- 1 file changed, 49 insertions(+), 19 deletions(-) diff --git a/src/console/clients/checker/service.rs b/src/console/clients/checker/service.rs index 5f464fbd1..02bf1926b 100644 --- a/src/console/clients/checker/service.rs +++ b/src/console/clients/checker/service.rs @@ -1,13 +1,18 @@ use std::net::SocketAddr; +use std::str::FromStr; use std::sync::Arc; use std::time::Duration; use colored::Colorize; -use reqwest::{Client, Url}; +use reqwest::{Client as HttpClient, Url}; use super::config::Configuration; use super::console::Console; use crate::console::clients::checker::printer::Printer; +use crate::shared::bit_torrent::info_hash::InfoHash; +use crate::shared::bit_torrent::tracker::http::client::requests::announce::QueryBuilder; +use crate::shared::bit_torrent::tracker::http::client::responses::announce::Announce; +use crate::shared::bit_torrent::tracker::http::client::Client; pub struct Service { pub(crate) config: Arc, @@ -19,7 +24,7 @@ pub type CheckResult = Result<(), CheckError>; #[derive(Debug)] pub enum CheckError { UdpError, - HttpError, + HttpError { url: Url }, HealthCheckError { url: Url }, } @@ -30,10 +35,15 @@ impl Service { pub async fn run_checks(&self) -> Vec { self.console.println("Running checks for trackers ..."); + let mut check_results = vec![]; + self.check_udp_trackers(); - self.check_http_trackers(); - self.run_health_checks().await + self.check_http_trackers(&mut check_results).await; + + self.run_health_checks(&mut check_results).await; + + check_results } fn check_udp_trackers(&self) { @@ -44,27 +54,26 @@ impl Service { } } - fn check_http_trackers(&self) { + async fn check_http_trackers(&self, check_results: &mut Vec) { self.console.println("HTTP trackers ..."); for http_tracker in &self.config.http_trackers { - self.check_http_tracker(http_tracker); + match self.check_http_tracker(http_tracker).await { + Ok(()) => check_results.push(Ok(())), + Err(err) => check_results.push(Err(err)), + } } } - async fn run_health_checks(&self) -> Vec { + async fn run_health_checks(&self, check_results: &mut Vec) { self.console.println("Health checks ..."); - let mut check_results = vec![]; - for health_check_url in &self.config.health_checks { match self.run_health_check(health_check_url.clone()).await { Ok(()) => check_results.push(Ok(())), Err(err) => check_results.push(Err(err)), } } - - check_results } fn check_udp_tracker(&self, address: &SocketAddr) { @@ -72,19 +81,40 @@ impl Service { // - Make announce request // - Make scrape request self.console - .println(&format!("{} - UDP tracker at {:?} is OK (TODO)", "✓".green(), address)); + .println(&format!("{} - UDP tracker at udp://{:?} is OK (TODO)", "✓".green(), address)); } - fn check_http_tracker(&self, url: &Url) { - // todo: - // - Make announce request - // - Make scrape request - self.console - .println(&format!("{} - HTTP tracker at {} is OK (TODO)", "✓".green(), url)); + async fn check_http_tracker(&self, url: &Url) -> Result<(), CheckError> { + let info_hash_str = "9c38422213e30bff212b30c360d26f9a02136422".to_string(); // # DevSkim: ignore DS173237 + let info_hash = InfoHash::from_str(&info_hash_str).expect("a valid info-hash is required"); + + // Announce request + + let response = Client::new(url.clone()) + .announce(&QueryBuilder::with_default_values().with_info_hash(&info_hash).query()) + .await; + + if let Ok(body) = response.bytes().await { + if let Ok(_announce_response) = serde_bencode::from_bytes::(&body) { + self.console.println(&format!("{} - Announce at {} is OK", "✓".green(), url)); + + Ok(()) + } else { + self.console.println(&format!("{} - Announce at {} failing", "✗".red(), url)); + Err(CheckError::HttpError { url: url.clone() }) + } + } else { + self.console.println(&format!("{} - Announce at {} failing", "✗".red(), url)); + Err(CheckError::HttpError { url: url.clone() }) + } + + // Scrape request + + // todo } async fn run_health_check(&self, url: Url) -> Result<(), CheckError> { - let client = Client::builder().timeout(Duration::from_secs(5)).build().unwrap(); + let client = HttpClient::builder().timeout(Duration::from_secs(5)).build().unwrap(); match client.get(url.clone()).send().await { Ok(response) => {