From d10ac4cc08d679e7971296b79c6eafadcdbc78de Mon Sep 17 00:00:00 2001 From: Namilskyy Date: Sat, 29 Nov 2025 20:26:35 +0300 Subject: Big refactors and additions, implemented http package getter and refactored i2p fn --- src/i2impl/mi2p.rs | 162 ----------------------------------------------------- 1 file changed, 162 deletions(-) delete mode 100644 src/i2impl/mi2p.rs (limited to 'src/i2impl/mi2p.rs') diff --git a/src/i2impl/mi2p.rs b/src/i2impl/mi2p.rs deleted file mode 100644 index cf2b8e5..0000000 --- a/src/i2impl/mi2p.rs +++ /dev/null @@ -1,162 +0,0 @@ - -use crate::cfg::config::Config; - -use tokio; -use emissary_core::runtime::{ - AsyncRead, - AsyncWrite, -}; - -use std::{io, - fs::File, - path::Path, - io::Write}; -// use emissary_core::Profile; -// use emissary_core::i2np::Message; -use tokio::io::{AsyncReadExt, AsyncWriteExt}; -use yosemite::SessionOptions; -use yosemite::{Session, style::Stream}; -/* -use i2p_client::ClientType; -use i2p_client::I2PClient; -use i2p_client::SessionStyle::Stream; -use i2p_client::Session; - -struct I2PStatus { - Connected: bool, -} - -impl I2PStatus { - pub fn connect(&self) -> Result { - - let config: Config = Config::parse().unwrap(); - let client= I2PClient::new(true, "MeskPKG-manager".to_string(), "2.0", "2.58.0", 10); - // let destination = Session::r#gen(&mut self, SigType::EdDsaSha512Ed25519) - let session = Session::create(config.repo.repo_url, - &config.repo.destination.0, - "MeskPKG-manager", - Stream, - "2.0", - "2.58"); - - Ok(true) - } -} -*/ - -pub struct I2P { - session: Option>, - connected: bool, - config: Config, - -} - -impl I2P { - /// Creates a new I2P object with the given configuration. - /// - /// # Returns - /// - /// A new I2P object with the given configuration. The session is initially set to None and the connected status is set to false. - pub fn new(config: Config) -> Self { - I2P { - session: None, - connected: false, - config: config, - } - } - - /// Fetches the list of packages from the repository specified in the configuration. - /// - /// This function connects to the repository specified in the configuration, sends a GET request for the repository list and returns true if the request is successful, false otherwise. - /// - /// # Errors - /// - /// Returns an error if the repository URL is invalid or if the request fails. - /// - /// # Shortcomings - /// - Currently, &str is used instead of Path. - /// - An incomplete I2P structure, the session is stored in the structure but - /// is recreated when called, perhaps the connection/disconnection methods should be encapsulated, - /// although the function is not used often so it will not carry major changes - pub async fn fetch_index(&mut self) -> Result { - let repo_url_str = &self.config.repo.repo_url; - let cache_dir = &self.config.paths.cache_dir; - - let repo_pos = repo_url_str.find("/repo").ok_or_else(|| { - io::Error::new(io::ErrorKind::InvalidData, "URL does not contain '/repo'") - })?; - // BaseURL - let base_url = &repo_url_str[..repo_pos]; - // Url after /repo - let path_suffix = &repo_url_str[repo_pos + "/repo".len()..]; - // HTTP path - let request_path = format!("/repo{}{}", path_suffix, if path_suffix.ends_with(".tar.gz") { "" } else { "/INDEX.tar.gz" }); - - let opts = SessionOptions::default(); - // FIXME: Make sure, opts setted to I2P - // opts.set_host("127.0.0.1"); - // opts.set_port(7656); - let mut session = Session::::new(opts).await.map_err(|e| { - io::Error::new(io::ErrorKind::Other, format!("Failed to create session: {}", e)) - })?; - - let mut stream = session.connect(base_url).await.map_err(|e| { - io::Error::new(io::ErrorKind::ConnectionAborted, format!("Failed to connect: {}", e)) - })?; - - let request = format!("GET {} HTTP/1.1\r\nHost: {}\r\n\r\n", request_path, base_url); - stream.write_all(request.as_bytes()).await.map_err(|e| { - io::Error::new(io::ErrorKind::Other, format!("Failed to write request: {}", e)) - })?; - - let mut response_buffer = Vec::new(); - let mut chunk = [0u8; 1024]; - - loop { - // FIXME: Check docs and make suro stream allows to AsyncReadExt - let bytes_read = stream.read(&mut chunk).await.map_err(|e| { - io::Error::new(io::ErrorKind::Other, format!("Failed to read response: {}", e)) - })?; - - if bytes_read == 0 { - break; - } - - response_buffer.extend_from_slice(&chunk[..bytes_read]); - - if let Some(headers_end) = Self::find_double_crlf(&response_buffer) { - let body_start = headers_end + 4; - let headers_str = std::str::from_utf8(&response_buffer[..headers_end]) - .map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "Invalid header encoding"))?; - - if !headers_str.starts_with("HTTP/1.1 200") && !headers_str.starts_with("HTTP/1.0 200") { - return Err(io::Error::new(io::ErrorKind::Other, format!("HTTP Error: {}", headers_str.lines().next().unwrap_or("Unknown")))); - } - - let file_path = Path::new(cache_dir).join("INDEX.tar.gz"); - let mut file = File::create(&file_path)?; - file.write_all(&response_buffer[body_start..])?; - while let Ok(bytes_read) = stream.read(&mut chunk).await { - if bytes_read == 0 { - break; - } - file.write_all(&chunk[..bytes_read])?; - } - - file.flush()?; - break; - } - } - - Ok(true) - } - - fn find_double_crlf(buf: &[u8]) -> Option { - for i in 0..buf.len().saturating_sub(3) { - if buf[i] == b'\r' && buf[i+1] == b'\n' && buf[i+2] == b'\r' && buf[i+3] == b'\n' { - return Some(i); - } - } - None - } -} \ No newline at end of file -- cgit v1.2.3