102 lines
2.7 KiB
Rust
102 lines
2.7 KiB
Rust
use std::{
|
|
env, fs,
|
|
net::SocketAddr,
|
|
path::{Path, PathBuf},
|
|
};
|
|
use axum::{
|
|
routing::{get, post},
|
|
extract::Json,
|
|
Router,
|
|
response::Html,
|
|
};
|
|
use tower_http::services::ServeDir;
|
|
use serde::Deserialize;
|
|
|
|
mod assets;
|
|
use assets::{DEFAULT_INDEX_HTML, DEFAULT_APP_JS, DEFAULT_STYLES_CSS};
|
|
|
|
use crate::{state::SharedState, headless};
|
|
|
|
const WEB_DIR: &str = "web";
|
|
|
|
fn exe_dir() -> PathBuf {
|
|
env::current_exe()
|
|
.ok()
|
|
.and_then(|p| p.parent().map(|p| p.to_path_buf()))
|
|
.unwrap_or_else(|| PathBuf::from("."))
|
|
}
|
|
|
|
fn rebuild_web_assets(dir: &Path) -> std::io::Result<()> {
|
|
let web = dir.join(WEB_DIR);
|
|
if web.exists() {
|
|
fs::remove_dir_all(&web)?;
|
|
}
|
|
fs::create_dir_all(&web)?;
|
|
fs::write(web.join("index.html"), DEFAULT_INDEX_HTML.trim_start())?;
|
|
fs::write(web.join("app.js"), DEFAULT_APP_JS.trim_start())?;
|
|
fs::write(web.join("styles.css"), DEFAULT_STYLES_CSS.trim_start())?;
|
|
Ok(())
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
struct StartRequest {
|
|
ip: String,
|
|
}
|
|
|
|
async fn start_job(Json(req): Json<StartRequest>) -> String {
|
|
let ip = req.ip.trim().to_string();
|
|
println!("[WebServer] Starte Headless-Test für {}", ip);
|
|
|
|
// Klon für den Task
|
|
let ip_for_task = ip.clone();
|
|
|
|
tokio::spawn(async move {
|
|
if let Err(e) = headless::run_test(&ip_for_task).await {
|
|
eprintln!("[Headless Error] {}", e);
|
|
}
|
|
});
|
|
|
|
format!("Starte Setup für {}", ip)
|
|
|
|
}
|
|
|
|
// Port wird jetzt von außen übergeben
|
|
pub async fn start(state: SharedState, port: u16)
|
|
-> Result<tokio::task::JoinHandle<()>, Box<dyn std::error::Error>>
|
|
{
|
|
let dir = exe_dir();
|
|
rebuild_web_assets(&dir)?;
|
|
|
|
let web_root = dir.join(WEB_DIR);
|
|
let static_root = web_root.clone();
|
|
let index_path = web_root.join("index.html");
|
|
|
|
let app = Router::new()
|
|
.route("/", get({
|
|
let index_path = index_path.clone();
|
|
move || {
|
|
let index_path = index_path.clone();
|
|
async move {
|
|
let html = fs::read_to_string(&index_path)
|
|
.unwrap_or_else(|_| "<h1>index.html fehlt</h1>".to_string());
|
|
Html(html)
|
|
}
|
|
}
|
|
}))
|
|
.route("/api/start", post(start_job)) // 👈 Neue Route
|
|
.nest_service("/static", ServeDir::new(static_root))
|
|
.route("/healthz", get(|| async { "ok" }));
|
|
|
|
{
|
|
let mut s = state.lock().unwrap();
|
|
s.web_server_active = true;
|
|
}
|
|
|
|
let addr: SocketAddr = format!("0.0.0.0:{}", port).parse()?;
|
|
let listener = tokio::net::TcpListener::bind(addr).await?;
|
|
let handle = tokio::spawn(async move {
|
|
let _ = axum::serve(listener, app).await;
|
|
});
|
|
|
|
Ok(handle)
|
|
}
|