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() {
|
||||
println!("Hello, world!");
|
||||
mod api;
|
||||
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