use actix_web::client::ClientBuilder; use actix_web::middleware::Logger; use actix_web::{App, HttpServer}; use hotwatch::{Event, Hotwatch}; use rustypaste::config::Config; use rustypaste::paste::PasteType; use rustypaste::server; use std::env; use std::fs; use std::io::Result as IoResult; use std::path::PathBuf; use std::sync::{Arc, Mutex}; use std::time::Duration; #[actix_web::main] async fn main() -> IoResult<()> { // Initialize logger. env_logger::init_from_env(env_logger::Env::new().default_filter_or("info")); // Parse configuration. dotenv::dotenv().ok(); let config_path = PathBuf::from(env::var("CONFIG").unwrap_or_else(|_| String::from("config.toml"))); let config = Arc::new(Mutex::new( Config::parse(&config_path).expect("failed to parse config"), )); let cloned_config = Arc::clone(&config); let server_config = config.lock().expect("cannot acquire config").server.clone(); // Create necessary directories. fs::create_dir_all(&server_config.upload_path)?; for paste_type in &[PasteType::Url, PasteType::Oneshot] { fs::create_dir_all(paste_type.get_path(&server_config.upload_path))?; } // Set up a watcher for the configuration file changes. let mut hotwatch = Hotwatch::new_with_custom_delay(Duration::from_secs(1)) .expect("failed to initialize configuration file watcher"); // Hot-reload the configuration file. hotwatch .watch(&config_path, move |event: Event| { if let Event::Write(path) = event { match Config::parse(&path) { Ok(config) => { *cloned_config.lock().expect("cannot acquire config") = config; log::info!("Configuration has been updated."); } Err(e) => { log::error!("Failed to update configuration: {}", e); } } } }) .unwrap_or_else(|_| panic!("failed to watch {:?}", config_path)); // Create a HTTP server. let mut http_server = HttpServer::new(move || { let http_client = ClientBuilder::default() .timeout(Duration::from_secs(30)) .disable_redirects() .finish(); App::new() .data(Arc::clone(&config)) .data(http_client) .wrap(Logger::default()) .configure(server::configure_routes) }) .bind(server_config.address)?; // Set worker count for the server. if let Some(workers) = server_config.workers { http_server = http_server.workers(workers); } // Run the server. http_server.run().await }