11use std:: net:: SocketAddr ;
2+ use std:: str:: FromStr ;
23use std:: sync:: Arc ;
34use std:: time:: Duration ;
45
56use colored:: Colorize ;
6- use reqwest:: { Client , Url } ;
7+ use reqwest:: { Client as HttpClient , Url } ;
78
89use super :: config:: Configuration ;
910use super :: console:: Console ;
1011use crate :: console:: clients:: checker:: printer:: Printer ;
12+ use crate :: shared:: bit_torrent:: info_hash:: InfoHash ;
13+ use crate :: shared:: bit_torrent:: tracker:: http:: client:: requests:: announce:: QueryBuilder ;
14+ use crate :: shared:: bit_torrent:: tracker:: http:: client:: responses:: announce:: Announce ;
15+ use crate :: shared:: bit_torrent:: tracker:: http:: client:: Client ;
1116
1217pub struct Service {
1318 pub ( crate ) config : Arc < Configuration > ,
@@ -19,7 +24,7 @@ pub type CheckResult = Result<(), CheckError>;
1924#[ derive( Debug ) ]
2025pub enum CheckError {
2126 UdpError ,
22- HttpError ,
27+ HttpError { url : Url } ,
2328 HealthCheckError { url : Url } ,
2429}
2530
@@ -30,10 +35,15 @@ impl Service {
3035 pub async fn run_checks ( & self ) -> Vec < CheckResult > {
3136 self . console . println ( "Running checks for trackers ..." ) ;
3237
38+ let mut check_results = vec ! [ ] ;
39+
3340 self . check_udp_trackers ( ) ;
34- self . check_http_trackers ( ) ;
3541
36- self . run_health_checks ( ) . await
42+ self . check_http_trackers ( & mut check_results) . await ;
43+
44+ self . run_health_checks ( & mut check_results) . await ;
45+
46+ check_results
3747 }
3848
3949 fn check_udp_trackers ( & self ) {
@@ -44,47 +54,67 @@ impl Service {
4454 }
4555 }
4656
47- fn check_http_trackers ( & self ) {
57+ async fn check_http_trackers ( & self , check_results : & mut Vec < CheckResult > ) {
4858 self . console . println ( "HTTP trackers ..." ) ;
4959
5060 for http_tracker in & self . config . http_trackers {
51- self . check_http_tracker ( http_tracker) ;
61+ match self . check_http_tracker ( http_tracker) . await {
62+ Ok ( ( ) ) => check_results. push ( Ok ( ( ) ) ) ,
63+ Err ( err) => check_results. push ( Err ( err) ) ,
64+ }
5265 }
5366 }
5467
55- async fn run_health_checks ( & self ) -> Vec < CheckResult > {
68+ async fn run_health_checks ( & self , check_results : & mut Vec < CheckResult > ) {
5669 self . console . println ( "Health checks ..." ) ;
5770
58- let mut check_results = vec ! [ ] ;
59-
6071 for health_check_url in & self . config . health_checks {
6172 match self . run_health_check ( health_check_url. clone ( ) ) . await {
6273 Ok ( ( ) ) => check_results. push ( Ok ( ( ) ) ) ,
6374 Err ( err) => check_results. push ( Err ( err) ) ,
6475 }
6576 }
66-
67- check_results
6877 }
6978
7079 fn check_udp_tracker ( & self , address : & SocketAddr ) {
7180 // todo:
7281 // - Make announce request
7382 // - Make scrape request
7483 self . console
75- . println ( & format ! ( "{} - UDP tracker at {:?} is OK (TODO)" , "✓" . green( ) , address) ) ;
84+ . println ( & format ! ( "{} - UDP tracker at udp:// {:?} is OK (TODO)" , "✓" . green( ) , address) ) ;
7685 }
7786
78- fn check_http_tracker ( & self , url : & Url ) {
79- // todo:
80- // - Make announce request
81- // - Make scrape request
82- self . console
83- . println ( & format ! ( "{} - HTTP tracker at {} is OK (TODO)" , "✓" . green( ) , url) ) ;
87+ async fn check_http_tracker ( & self , url : & Url ) -> Result < ( ) , CheckError > {
88+ let info_hash_str = "9c38422213e30bff212b30c360d26f9a02136422" . to_string ( ) ; // # DevSkim: ignore DS173237
89+ let info_hash = InfoHash :: from_str ( & info_hash_str) . expect ( "a valid info-hash is required" ) ;
90+
91+ // Announce request
92+
93+ let response = Client :: new ( url. clone ( ) )
94+ . announce ( & QueryBuilder :: with_default_values ( ) . with_info_hash ( & info_hash) . query ( ) )
95+ . await ;
96+
97+ if let Ok ( body) = response. bytes ( ) . await {
98+ if let Ok ( _announce_response) = serde_bencode:: from_bytes :: < Announce > ( & body) {
99+ self . console . println ( & format ! ( "{} - Announce at {} is OK" , "✓" . green( ) , url) ) ;
100+
101+ Ok ( ( ) )
102+ } else {
103+ self . console . println ( & format ! ( "{} - Announce at {} failing" , "✗" . red( ) , url) ) ;
104+ Err ( CheckError :: HttpError { url : url. clone ( ) } )
105+ }
106+ } else {
107+ self . console . println ( & format ! ( "{} - Announce at {} failing" , "✗" . red( ) , url) ) ;
108+ Err ( CheckError :: HttpError { url : url. clone ( ) } )
109+ }
110+
111+ // Scrape request
112+
113+ // todo
84114 }
85115
86116 async fn run_health_check ( & self , url : Url ) -> Result < ( ) , CheckError > {
87- let client = Client :: builder ( ) . timeout ( Duration :: from_secs ( 5 ) ) . build ( ) . unwrap ( ) ;
117+ let client = HttpClient :: builder ( ) . timeout ( Duration :: from_secs ( 5 ) ) . build ( ) . unwrap ( ) ;
88118
89119 match client. get ( url. clone ( ) ) . send ( ) . await {
90120 Ok ( response) => {
0 commit comments