From 8cedf3da99949f4ba5e3bfa9d73b436ee1aa6ee1 Mon Sep 17 00:00:00 2001 From: Sudo Dios Date: Sun, 1 Sep 2024 14:42:27 +0330 Subject: [PATCH] Handle http client errors --- src/http/http_client.rs | 43 +++++++++++++++++++++------------------- src/ip/ip_info.rs | 44 ++++++++++++++++++++++------------------- src/ip/mod.rs | 8 ++++++-- 3 files changed, 53 insertions(+), 42 deletions(-) diff --git a/src/http/http_client.rs b/src/http/http_client.rs index f4f6fd6..f0af318 100644 --- a/src/http/http_client.rs +++ b/src/http/http_client.rs @@ -1,5 +1,5 @@ use std::fs::File; -use std::io::Error; +use std::io::{Error, ErrorKind}; use std::pin::Pin; use std::task::{Context, Poll}; use serde_json::Value; @@ -55,28 +55,28 @@ impl AsyncWrite for ClientStream { impl HttpClient { - pub async fn open(url : &str) -> Self { - let pared_url = Self::parse_url(url); - let tcp_stream = TcpStream::connect(format!("{}:{}",pared_url.1,pared_url.2)).await.unwrap(); + pub async fn open(url : &str) -> std::io::Result { + let pared_url = Self::parse_url(url)?; + let tcp_stream = TcpStream::connect(format!("{}:{}",pared_url.1,pared_url.2)).await?; let stream = if pared_url.2 == 443 { let tls_stream = setup_tls_connector(pared_url.1.clone(),tcp_stream).await; ClientStream::Tls(tls_stream) } else { ClientStream::Tcp(tcp_stream) }; - HttpClient { + Ok(HttpClient { host : pared_url.1, path : pared_url.3, stream - } + }) } - pub async fn send_request_json(&mut self,packet : &[u8]) -> Option { - self.stream.write_all(packet).await.unwrap(); + pub async fn send_request_json(&mut self,packet : &[u8]) -> std::io::Result> { + self.stream.write_all(packet).await?; let mut read_data = Vec::new(); loop { let mut response = vec![0; 128]; - let read = self.stream.read(&mut response).await.unwrap(); + let read = self.stream.read(&mut response).await?; read_data.extend(response); if read < 128 { //EOF break; @@ -88,12 +88,12 @@ impl HttpClient { let mut split_body = response.splitn(2,"\r\n\r\n"); let resp_body = split_body.nth(1).unwrap_or(""); if let Ok(parsed_json_body) = serde_json::from_str::(resp_body) { - Some(parsed_json_body) + Ok(Some(parsed_json_body)) } else { - None + Ok(None) } } else { - None + Ok(None) } } @@ -142,15 +142,18 @@ impl HttpClient { } } - fn parse_url(url: &str) -> (String,String,i32,String) { - let (scheme, rest) = url.split_once("://").unwrap(); - let (host, path) = if rest.contains('/') { - rest.split_once('/').unwrap() + fn parse_url(url: &str) -> std::io::Result<(String,String,i32,String)> { + if let Some((scheme, rest)) = url.split_once("://") { + let (host, path) = if rest.contains('/') { + rest.split_once('/').unwrap() + } else { + (rest,"") + }; + let port = if scheme == "https" { 443 } else { 80 }; + Ok((scheme.to_string(),host.to_string(),port,path.to_string())) } else { - (rest,"") - }; - let port = if scheme == "https" { 443 } else { 80 }; - (scheme.to_string(),host.to_string(),port,path.to_string()) + Err(Error::new(ErrorKind::Other,"Error parsing input url")) + } } } \ No newline at end of file diff --git a/src/ip/ip_info.rs b/src/ip/ip_info.rs index 2286c7e..5eeed59 100644 --- a/src/ip/ip_info.rs +++ b/src/ip/ip_info.rs @@ -122,33 +122,37 @@ impl IPInfo { } async fn get_isp_info_from_api(ip : &str) -> Option { - let config = SERVER_CONFIG.get().unwrap(); + let config = SERVER_CONFIG.get()?; let ip_info_token = config.ipinfo_api_key.clone(); if ip_info_token.is_empty() { return None } - let mut client = HttpClient::open("https://ipinfo.io").await; - let request = format!( - "GET /{}/json?token={} HTTP/1.1\r\n\ + if let Ok(mut client) = HttpClient::open("https://ipinfo.io").await { + let request = format!( + "GET /{}/json?token={} HTTP/1.1\r\n\ Host: ipinfo.io\r\n\r\n", - ip, - ip_info_token - ); - if let Some(res_body) = client.send_request_json(request.as_bytes()).await { - let isp = if let Some(org) = res_body.get("org") { - Some(org.as_str().unwrap()) - } else { - let asn_name = &res_body["asn"]["name"]; - if !asn_name.is_null() { - Some(asn_name.as_str().unwrap()) + ip, + ip_info_token + ); + if let Ok(Some(res_body)) = client.send_request_json(request.as_bytes()).await { + let isp = if let Some(org) = res_body.get("org") { + Some(org.as_str()?) } else { - None - } - }; - isp.as_ref()?; - let output = format!("{} - {}, {}",ip,isp.unwrap(),res_body.get("country").unwrap().as_str().unwrap()); - Some(output) + let asn_name = &res_body["asn"]["name"]; + if !asn_name.is_null() { + Some(asn_name.as_str()?) + } else { + None + } + }; + isp.as_ref()?; + let output = format!("{} - {}, {}",ip,isp?,res_body.get("country")?.as_str()?); + Some(output) + } else { + None + } } else { + warn!("Http client error."); None } } diff --git a/src/ip/mod.rs b/src/ip/mod.rs index c62dd6f..c94fa97 100644 --- a/src/ip/mod.rs +++ b/src/ip/mod.rs @@ -1,3 +1,4 @@ +use log::error; use tokio::runtime::Runtime; use crate::http::http_client::HttpClient; @@ -7,7 +8,10 @@ pub mod mmdb; pub fn update_ipdb(url : &str,file_name : &str) { let runtime = Runtime::new().unwrap(); runtime.block_on(async { - let mut client = HttpClient::open(url).await; - client.download_file(file_name).await; + if let Ok(mut client) = HttpClient::open(url).await { + client.download_file(file_name).await; + } else { + error!("Http client error.") + } }); } \ No newline at end of file