summaryrefslogtreecommitdiff
path: root/src/i2impl/mi2p.rs
blob: e0bbe3d8d89f045dd3c2e7c0f64c811528b737bf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101

use crate::cfg::config::Config;  

use tokio;

use emissary_core::runtime::{
    AsyncRead, 
    AsyncWrite, 
};
use std::io; 
use emissary_core::Profile; 
use emissary_core::i2np::Message;
use tokio::io::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<bool, std::io::Error> {

        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)
    }
}
*/

struct I2P<S> {
    session: Option<Session<S>>,
    connected: bool, 
    config: Config,

}

impl<S> I2P<S> {
    /// 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.
    ///
    async fn fetch(&mut self) -> Result<bool, std::io::Error> {
        let repo_url_str = &self.config.repo.repo_url;

        let repo_pos = repo_url_str.find("/repo").ok_or_else(|| {
            io::Error::new(io::ErrorKind::InvalidData, "URL does not contain '/repo'")
        })?;
        let base_url = &repo_url_str[..repo_pos];
        let path_suffix = &repo_url_str[repo_pos + "/repo".len()..];
        let request_path = format!("/repo{}{}", path_suffix, if path_suffix.ends_with(".tar.gz") { "" } else { "/INDEX.tar.gz" });
        let opts = SessionOptions::default();

        // opts.set_host("127.0.0.1");
        // opts.set_port(7656);       
        let mut session = Session::<Stream>::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::ConnectionReset, 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))
        })?;

        Ok(true)
}
}