server: main.rs — Actix-web entry point with CORS, compression, static serving, SPA fallback; placeholder static/index.html
This commit is contained in:
parent
a0b834ed15
commit
0c35db1746
@ -1,3 +1,91 @@
|
|||||||
fn main() {
|
mod api;
|
||||||
println!("Hello, world!");
|
mod config;
|
||||||
|
mod models;
|
||||||
|
mod state;
|
||||||
|
mod stream;
|
||||||
|
mod ws;
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use actix_cors::Cors;
|
||||||
|
use actix_web::{web, App, HttpServer, middleware};
|
||||||
|
use log::info;
|
||||||
|
|
||||||
|
use config::Config;
|
||||||
|
use state::AppState;
|
||||||
|
|
||||||
|
#[actix_web::main]
|
||||||
|
async fn main() -> std::io::Result<()> {
|
||||||
|
// Initialize logger from RUST_LOG env var (default: info).
|
||||||
|
env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
|
||||||
|
|
||||||
|
let config = Config::from_env();
|
||||||
|
let bind_addr = config.bind_addr();
|
||||||
|
|
||||||
|
info!("🦋 Butterfly Server v{}", env!("CARGO_PKG_VERSION"));
|
||||||
|
info!(" config: {:?}", &config);
|
||||||
|
|
||||||
|
let app_state = AppState::new(
|
||||||
|
config.max_sessions,
|
||||||
|
config.idle_timeout_secs,
|
||||||
|
config.frame_buffer_size,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Build CORS middleware.
|
||||||
|
let cors = if config.cors_origins.iter().any(|o| o == "*") {
|
||||||
|
Cors::permissive()
|
||||||
|
} else {
|
||||||
|
let mut cors = Cors::default();
|
||||||
|
for origin in &config.cors_origins {
|
||||||
|
cors = cors.allowed_origin(origin);
|
||||||
|
}
|
||||||
|
cors
|
||||||
|
};
|
||||||
|
|
||||||
|
// Path to the Angular frontend build output (relative to server/).
|
||||||
|
// Falls back to "static" if the Angular dist dir doesn't exist yet.
|
||||||
|
let frontend_dir = std::path::Path::new("../desktop/dist/browser");
|
||||||
|
let static_dir = if frontend_dir.exists() {
|
||||||
|
frontend_dir.to_path_buf()
|
||||||
|
} else {
|
||||||
|
std::path::PathBuf::from("static")
|
||||||
|
};
|
||||||
|
|
||||||
|
info!(" serving static files from: {:?}", static_dir);
|
||||||
|
|
||||||
|
HttpServer::new(move || {
|
||||||
|
let json_cfg = web::JsonConfig::default()
|
||||||
|
.limit(1024 * 1024) // 1 MB max JSON payload
|
||||||
|
.error_handler(|err, _req| {
|
||||||
|
let resp = actix_web::HttpResponse::BadRequest().json(
|
||||||
|
models::ApiResponse::<()>::err(format!("invalid JSON: {}", err)),
|
||||||
|
);
|
||||||
|
actix_web::error::InternalError::from_response(err, resp).into()
|
||||||
|
});
|
||||||
|
|
||||||
|
App::new()
|
||||||
|
.app_data(web::Data::new(app_state.clone()))
|
||||||
|
.app_data(json_cfg)
|
||||||
|
.wrap(cors.clone())
|
||||||
|
.wrap(middleware::Logger::default())
|
||||||
|
.wrap(middleware::Compress::default())
|
||||||
|
.configure(api::configure)
|
||||||
|
.configure(ws::configure)
|
||||||
|
// Serve Angular static assets; falls back to index.html for SPA routing.
|
||||||
|
.service(actix_files::Files::new("/assets", &static_dir.join("assets")).show_files_listing())
|
||||||
|
.route("/", web::get().to(|| async {
|
||||||
|
actix_web::HttpResponse::Ok()
|
||||||
|
.content_type("text/html; charset=utf-8")
|
||||||
|
.body(include_str!("../../static/index.html"))
|
||||||
|
}))
|
||||||
|
.default_service(web::route().to(|| async {
|
||||||
|
actix_web::HttpResponse::Ok()
|
||||||
|
.content_type("text/html; charset=utf-8")
|
||||||
|
.body(include_str!("../../static/index.html"))
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
.bind(&bind_addr)?
|
||||||
|
.workers(4)
|
||||||
|
.run()
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|||||||
21
server/static/index.html
Normal file
21
server/static/index.html
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Butterfly Desktop</title>
|
||||||
|
<style>
|
||||||
|
body { margin: 0; font-family: system-ui, sans-serif; background: #0078d4; color: #fff; display: flex; align-items: center; justify-content: center; height: 100vh; }
|
||||||
|
.loader { text-align: center; }
|
||||||
|
.spinner { border: 4px solid rgba(255,255,255,.3); border-top: 4px solid #fff; border-radius: 50%; width: 48px; height: 48px; animation: spin 1s linear infinite; margin: 0 auto 16px; }
|
||||||
|
@keyframes spin { to { transform: rotate(360deg); } }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="loader">
|
||||||
|
<div class="spinner"></div>
|
||||||
|
<p>Butterfly Desktop Environment — loading…</p>
|
||||||
|
</div>
|
||||||
|
<!-- Angular app will replace this once built -->
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Loading…
Reference in New Issue
Block a user