From da276b034f18bde915efa7648ce5bbfec5d29ecb Mon Sep 17 00:00:00 2001 From: prplV Date: Thu, 5 Jun 2025 15:54:18 +0300 Subject: [PATCH] proxy created --- Cargo.toml | 2 +- noxis-proxy/.env.example | 2 + noxis-proxy/Cargo.toml | 12 +++++ noxis-proxy/src/main.rs | 98 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 noxis-proxy/.env.example create mode 100644 noxis-proxy/Cargo.toml create mode 100644 noxis-proxy/src/main.rs diff --git a/Cargo.toml b/Cargo.toml index 5b477a0..645c6e3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ resolver = "2" members = [ "noxis-rs", - "noxis-cli", + "noxis-cli", "noxis-proxy", ] [profile.dev] diff --git a/noxis-proxy/.env.example b/noxis-proxy/.env.example new file mode 100644 index 0000000..e67257a --- /dev/null +++ b/noxis-proxy/.env.example @@ -0,0 +1,2 @@ +NOXIS_SOCKET_PATH = "/path/to/noxis.sock" +NOXIS_PROXY_PORT = "numport" \ No newline at end of file diff --git a/noxis-proxy/Cargo.toml b/noxis-proxy/Cargo.toml new file mode 100644 index 0000000..75dd591 --- /dev/null +++ b/noxis-proxy/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "noxis-proxy" +version = "0.1.0" +edition = "2024" + +[dependencies] +anyhow = "1.0.98" +axum = { version = "0.8.4", features = ["ws"] } +dotenv = "0.15.0" +tokio = { version = "1.45.1", features = ["full"] } +tracing = "0.1.41" +tracing-subscriber = "0.3.19" diff --git a/noxis-proxy/src/main.rs b/noxis-proxy/src/main.rs new file mode 100644 index 0000000..3e31775 --- /dev/null +++ b/noxis-proxy/src/main.rs @@ -0,0 +1,98 @@ +use axum::{ + extract::{ + ws::{Message, WebSocket, WebSocketUpgrade}, + State, + }, + response::IntoResponse, + routing::get, + Router, +}; +use std::{ + path::PathBuf, str::FromStr, +}; +use tokio::net::UnixStream; +use tokio::io::{AsyncReadExt, AsyncWriteExt}; + +#[derive(Clone)] +struct AppState { + socket_path: PathBuf, +} + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + dotenv::dotenv().ok(); + + tracing_subscriber::fmt() + .with_max_level(tracing::Level::from_str(&std::env::var("NOXIS_LOG_LEVEL").unwrap_or_else(|_| String::from("INFO"))).unwrap_or_else(|_| tracing::Level::INFO)) + .with_writer(std::io::stdout) + .compact() + .init(); + + let app_state = AppState { + socket_path : PathBuf::new().join(std::env::var("NOXIS_SOCKET_PATH").unwrap_or_else(|_| String::from("./noxis.sock"))) + }; + let app = Router::new() + .route("/ws", get(ws_handler)) + .route("/hello", get(hello)) + .with_state(app_state); + + let bind = format!("0.0.0.0:{}", std::env::var("NOXIS_PROXY_PORT").unwrap_or_else(|_| String::from("3000"))); + + tracing::info!("Serving on {}", &bind); + + let listener = tokio::net::TcpListener::bind(bind) + .await?; + axum::serve(listener, app).await?; + Ok(()) +} + +async fn ws_handler( + ws: WebSocketUpgrade, + State(state): State, +) -> impl IntoResponse { + tracing::info!("New WebSocket connection"); + ws.on_upgrade(|socket| handle_socket(socket, state)) +} + +async fn hello( + State(_state): State, +) -> impl IntoResponse { + String::from("HELLO") +} + +async fn handle_socket(mut ws: WebSocket, state: AppState) { + // Подключаемся к Unix-сокету + tracing::info!("handle websocket"); + let mut unix_socket = match UnixStream::connect(&state.socket_path).await { + Ok(socket) => socket, + Err(e) => { + eprintln!("Failed to connect to Unix socket: {}", e); + let _ = ws.send(Message::Text("ERROR: Unix socket connection failed".into())).await; + return; + } + }; + + // Отправляем сообщения из WS → Unix + let ws_receiver = tokio::spawn(async move { + while let Some(Ok(msg)) = ws.recv().await { + if let Message::Text(text) = msg { + if let Err(e) = unix_socket.write_all(text.as_bytes()).await { + eprintln!("Failed to write to Unix socket: {}", e); + break; + } + let mut buf = Vec::new(); + match unix_socket.read_to_end(&mut buf).await { + Ok(n) if n > 0 => { + let response = String::from_utf8_lossy(&buf[..n]); + if ws.send(Message::Text(response.into_owned().into())).await.is_err() { + break; + } + } + Ok(_) | Err(_) => break, + } + } + } + }); + + let _ = ws_receiver.await; // Дожидаемся завершения задачи +}