diff --git a/src/main.rs b/src/main.rs index b0d48774b4..9cfb3c23a0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,121 @@ +pub mod server_state; -pub fn main() { -} \ No newline at end of file +use actix_cors::Cors; +use actix_http::http; +use log::{info}; +use actix_web::middleware::{Logger, DefaultHeaders}; +use actix_web::{HttpServer, web, HttpResponse, App}; +use std::sync::Arc; +use crate::server_state::{ServerState, EnvConfig}; + +const DEFAULT_BIND_ADDRESS : &'static str = "0.0.0.0:12345"; +const DEFAULT_RUST_LOG: &'static str = "debug,actix_web=info"; + +pub type AnyhowResult = anyhow::Result; + +pub fn main() -> AnyhowResult<()> { + easyenv::init_all_with_default_logging(Some(DEFAULT_RUST_LOG)); + + let server_hostname = hostname::get() + .ok() + .and_then(|h| h.into_string().ok()) + .unwrap_or("storyteller-web-unknown".to_string()); + + let server_state = ServerState { + env_config: EnvConfig { + num_workers: 4, + bind_address: DEFAULT_BIND_ADDRESS.to_string(), + }, + hostname: server_hostname, + }; + + serve(server_state)?; + Ok(()) +} + +#[actix_web::main] +pub async fn serve(server_state: ServerState) -> std::io::Result<()> +{ + let bind_address = server_state.env_config.bind_address.clone(); + let num_workers = server_state.env_config.num_workers.clone(); + let hostname = server_state.hostname.clone(); + + let server_state_arc = web::Data::new(Arc::new(server_state)); + + info!("Starting HTTP service."); + + let log_format = "[%{HOSTNAME}e] %a \"%r\" %s %b \"%{Referer}i\" \"%{User-Agent}i\" %T"; + + HttpServer::new(move || { + let mut app = App::new() + .wrap(Cors::default() + .allowed_origin("http://api.vo.codes") + .allowed_origin("http://jungle.horse") + .allowed_origin("http://localhost:12345") + .allowed_origin("http://localhost:3000") + .allowed_origin("http://localhost:5555") + .allowed_origin("http://localhost:7000") + .allowed_origin("http://localhost:8000") + .allowed_origin("http://localhost:8080") + .allowed_origin("http://mumble.stream") + .allowed_origin("http://trumped.com") + .allowed_origin("http://vo.codes") + .allowed_origin("http://vocodes.com") + .allowed_origin("https://jungle.horse") + .allowed_origin("https://mumble.stream") + .allowed_origin("https://trumped.com") + .allowed_origin("https://vo.codes") + .allowed_origin("https://vocodes.com") + .allowed_methods(vec!["GET", "POST", "OPTIONS"]) + .allowed_headers(vec![ + http::header::ACCEPT, + http::header::ACCESS_CONTROL_ALLOW_ORIGIN, // Tabulator Ajax + http::header::CONTENT_TYPE, + http::header::HeaderName::from_static("x-requested-with") // Tabulator Ajax sends + ]) + .max_age(3600)) + .wrap(Logger::new(&log_format) + .exclude("/liveness") + .exclude("/readiness")) + .wrap(DefaultHeaders::new().header("X-Backend-Hostname", &hostname)) + .service( + web::resource("/test") + .route(web::get().to(|| HttpResponse::Ok())) + .route(web::head().to(|| HttpResponse::Ok())) + ); + // Admin UI & old frontend + //.service(Files::new("/frontend", admin_asset_directory.clone()) + // .index_file("FAKE_INDEX.HTML")) + //.service(Files::new("/adminui", admin_asset_directory.clone()) + // .index_file("index.html")) + // Early access static path for assets + //.service(Files::new("/static", static_asset_directory.clone()) + // .index_file("FAKE_INDEX.HTML")) + /*.service( + web::resource("/login") + .route(web::post().to(login_handler)) + .route(web::head().to(|| HttpResponse::Ok())) + ) + .service( + web::resource("/logout") + .route(web::post().to(logout_handler)) + .route(web::head().to(|| HttpResponse::Ok())) + ) + .service(get_liveness) + .service(get_models) + .service(get_readiness) + .service(get_root) + .service(get_sentences) + .service(get_service_settings) + .service(get_speakers) + .service(get_early_access_speakers) + .service(get_dynamic_early_access_speakers) + .service(get_words);*/ + + app.app_data(server_state_arc.clone()) + }) + .bind(bind_address)? + .workers(num_workers) + .run() + .await +} diff --git a/src/server_state.rs b/src/server_state.rs new file mode 100644 index 0000000000..9210cb51c3 --- /dev/null +++ b/src/server_state.rs @@ -0,0 +1,15 @@ + +/// State that is injected into every endpoint. +#[derive(Clone)] +pub struct ServerState { + pub env_config: EnvConfig, + + pub hostname: String, +} + +#[derive(Clone)] +pub struct EnvConfig { + // Number of thread workers. + pub num_workers: usize, + pub bind_address: String, +}