From df69b9de10e1c54e900669c27105cb661dcc8034 Mon Sep 17 00:00:00 2001 From: alterwain Date: Mon, 10 Mar 2025 02:10:53 +0300 Subject: [PATCH] modified: Cargo.lock modified: Cargo.toml modified: src/main.rs modified: src/tor.rs --- Cargo.lock | 1 + Cargo.toml | 1 + src/main.rs | 2 +- src/tor.rs | 80 +++++++++++++++++++++++++++++------------------------ 4 files changed, 47 insertions(+), 37 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 47535cd..f637027 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -25,6 +25,7 @@ dependencies = [ "tor-cell", "tor-hsservice", "tor-proto", + "tor-rtcompat", "tower-service", ] diff --git a/Cargo.toml b/Cargo.toml index 8988bfc..f60f30b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,7 @@ tor-cell = "0.28.0" tor-hsservice = "0.28.0" tor-proto = { version = "0.28.0", features = ["hs-service", "tokio"] } arti-client = { version = "0.28.0", features = ["tokio", "onion-service-service", "onion-service-client"]} +tor-rtcompat = "0.28.0" futures = "0.3" axum = { version = "0.8.1", features = ["macros"] } futures-util = "0.3.30" diff --git a/src/main.rs b/src/main.rs index 94ac719..31dc5f0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,7 +9,7 @@ mod tor; #[tokio::main] async fn main() { Builder::new() - .filter(None, LevelFilter::Debug) + .filter(None, LevelFilter::Info) .init(); /* let config = TorClientConfig::default(); diff --git a/src/tor.rs b/src/tor.rs index 2a73bde..5377835 100644 --- a/src/tor.rs +++ b/src/tor.rs @@ -1,6 +1,7 @@ use std::{error::Error, net::TcpListener, time::Duration}; use arti_client::{config::BoolOrAuto, StreamPrefs, TorClient, TorClientConfig}; +use axum::body::Bytes; use futures::{AsyncReadExt, Stream, StreamExt}; use log::{error, info}; use tor_hsservice::config::OnionServiceConfigBuilder; @@ -13,13 +14,14 @@ use axum::{ use axum::routing; use serde::{Deserialize, Serialize}; use futures::io::AsyncWriteExt; +use tor_rtcompat::PreferredRuntime; use crate::tor_axum; #[debug_handler] -async fn test_connection_to_tor(Json(payload): Json) -> (StatusCode, Json) { - info!("Got interesting payload! {}", payload.msg); - (StatusCode::OK, Json(SimpleMessage{ msg: "World is hell indeed!".to_string() })) +async fn test_connection_to_tor(payload: Bytes) -> (StatusCode, String) { + info!("Got interesting payload! {:#?}", payload); + (StatusCode::OK, "World is hell indeed!".to_string()) } #[derive(Serialize, Deserialize)] @@ -27,6 +29,41 @@ struct SimpleMessage { msg: String } +struct OnionHttpClient { + tor_client: TorClient +} + +impl OnionHttpClient { + pub async fn request(&self, path: &str, onion_name: String, data: Vec) -> Result> { + let mut stream_prefs = StreamPrefs::new(); + stream_prefs.connect_to_onion_services(BoolOrAuto::Explicit(true)); + + let mut stream = self.tor_client.connect_with_prefs((onion_name.clone(), 80), &stream_prefs).await?; + let host = onion_name; + + // Construct the HTTP request manually + let request = format!( + "POST {} HTTP/1.1\r\nHost: {}\r\nContent-Type: application/octet-stream\r\nContent-Length: {}\r\nConnection: close\r\n\r\n", + path, host, data.len() + ).as_bytes().to_vec(); + + let request = [request, data].concat(); + + stream.write_all(&request).await?; + + // Flushing the stream is important; see below! + let _ = stream.flush().await; + let mut buf = [0; 4096]; + let n = stream.read(&mut buf).await?; + Ok(String::from_utf8(buf[..n].to_vec()).unwrap()) + } +} + +pub async fn new_client() -> Result> { + let tor_client = TorClient::create_bootstrapped(TorClientConfig::default()).await?; + Ok(OnionHttpClient { tor_client }) +} + pub async fn start() -> Result<(), Box> { let tor_client = TorClient::create_bootstrapped(TorClientConfig::default()).await?; @@ -43,41 +80,12 @@ pub async fn start() -> Result<(), Box> { println!("serving at: http://{}", onion_service.onion_name().unwrap()); let onion_name = onion_service.onion_name().unwrap(); - tokio::spawn(async move { tokio::time::sleep(Duration::from_secs(40)).await; - - let mut stream_prefs = StreamPrefs::new(); - stream_prefs.connect_to_onion_services(BoolOrAuto::Explicit(true)); - - match tor_client.connect_with_prefs((onion_name.to_string(), 80), &stream_prefs).await { - Ok(mut stream) => { - - let host = onion_name.to_string(); - let path = "/"; - - // Construct the HTTP GET request manually - let request = format!( - "POST {} HTTP/1.1\r\nHost: {}\r\nContent-Type: application/json\r\nConnection: close\r\n\r\n{}", - path, host, serde_json::to_string(&SimpleMessage { msg: "is world hell?".to_string()}).unwrap() - ); - - if let Ok(a) = stream - .write_all(request.as_bytes()) - .await { - let _ = stream.flush().await; - let mut buf = [0; 4096]; - if let Ok(n) = stream.read(&mut buf).await { - info!("Got response!!! {}", String::from_utf8(buf[..n].to_vec()).unwrap()); - } else { - error!("No response!!!"); - } - // Flushing the stream is important; see below! - } else { - error!("GO NO MONEY"); - } - } - Err(err) => error!("Error: {}", err) + if let Ok(client) = new_client().await { + client.request("/", onion_name.to_string(), [1, 2, 2, 4, 8].to_vec()).await; + } else { + error!("Error creating new client!"); } });