2021-11-06 16:55:55 -04:00
|
|
|
use actix_web::client::ClientBuilder;
|
2021-07-19 18:35:52 -04:00
|
|
|
use actix_web::middleware::Logger;
|
2021-07-23 15:52:00 -04:00
|
|
|
use actix_web::{App, HttpServer};
|
2021-11-07 08:06:57 -05:00
|
|
|
use hotwatch::{Event, Hotwatch};
|
2021-07-24 13:46:22 -04:00
|
|
|
use rustypaste::config::Config;
|
2021-08-26 14:09:33 -04:00
|
|
|
use rustypaste::paste::PasteType;
|
2021-07-24 13:46:22 -04:00
|
|
|
use rustypaste::server;
|
2021-07-24 13:51:08 -04:00
|
|
|
use std::env;
|
2021-07-23 15:52:00 -04:00
|
|
|
use std::fs;
|
|
|
|
use std::io::Result as IoResult;
|
2021-11-07 08:06:57 -05:00
|
|
|
use std::path::PathBuf;
|
|
|
|
use std::sync::{Arc, Mutex};
|
2021-11-06 16:55:55 -04:00
|
|
|
use std::time::Duration;
|
2021-07-19 18:35:52 -04:00
|
|
|
|
|
|
|
#[actix_web::main]
|
2021-07-23 15:52:00 -04:00
|
|
|
async fn main() -> IoResult<()> {
|
2021-11-07 08:06:57 -05:00
|
|
|
// Initialize logger.
|
2021-07-19 18:35:52 -04:00
|
|
|
env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
|
2021-11-07 08:06:57 -05:00
|
|
|
|
|
|
|
// 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.
|
2021-08-04 10:35:54 -04:00
|
|
|
fs::create_dir_all(&server_config.upload_path)?;
|
2021-08-27 09:05:40 -04:00
|
|
|
for paste_type in &[PasteType::Url, PasteType::Oneshot] {
|
2021-08-26 15:57:46 -04:00
|
|
|
fs::create_dir_all(paste_type.get_path(&server_config.upload_path))?;
|
|
|
|
}
|
2021-11-07 08:06:57 -05:00
|
|
|
|
|
|
|
// 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.
|
2021-11-16 11:27:18 -05:00
|
|
|
let config_watcher = move |event: Event| {
|
|
|
|
if let Event::Write(path) = event {
|
|
|
|
match Config::parse(&path) {
|
|
|
|
Ok(config) => match cloned_config.lock() {
|
|
|
|
Ok(mut cloned_config) => {
|
|
|
|
*cloned_config = config;
|
2021-11-07 08:06:57 -05:00
|
|
|
log::info!("Configuration has been updated.");
|
|
|
|
}
|
|
|
|
Err(e) => {
|
2021-11-16 11:27:18 -05:00
|
|
|
log::error!("Failed to acquire configuration: {}", e);
|
2021-11-07 08:06:57 -05:00
|
|
|
}
|
2021-11-16 11:27:18 -05:00
|
|
|
},
|
|
|
|
Err(e) => {
|
|
|
|
log::error!("Failed to update configuration: {}", e);
|
2021-11-07 08:06:57 -05:00
|
|
|
}
|
|
|
|
}
|
2021-11-16 11:27:18 -05:00
|
|
|
}
|
|
|
|
};
|
|
|
|
hotwatch
|
|
|
|
.watch(&config_path, config_watcher)
|
2021-11-07 08:06:57 -05:00
|
|
|
.unwrap_or_else(|_| panic!("failed to watch {:?}", config_path));
|
|
|
|
|
|
|
|
// Create a HTTP server.
|
2021-07-23 15:52:00 -04:00
|
|
|
let mut http_server = HttpServer::new(move || {
|
2021-11-06 16:55:55 -04:00
|
|
|
let http_client = ClientBuilder::default()
|
|
|
|
.timeout(Duration::from_secs(30))
|
|
|
|
.disable_redirects()
|
|
|
|
.finish();
|
2021-07-23 15:52:00 -04:00
|
|
|
App::new()
|
2021-11-07 08:06:57 -05:00
|
|
|
.data(Arc::clone(&config))
|
2021-11-06 16:55:55 -04:00
|
|
|
.data(http_client)
|
2021-07-23 15:52:00 -04:00
|
|
|
.wrap(Logger::default())
|
|
|
|
.configure(server::configure_routes)
|
|
|
|
})
|
|
|
|
.bind(server_config.address)?;
|
2021-11-07 08:06:57 -05:00
|
|
|
|
|
|
|
// Set worker count for the server.
|
2021-07-23 15:52:00 -04:00
|
|
|
if let Some(workers) = server_config.workers {
|
|
|
|
http_server = http_server.workers(workers);
|
|
|
|
}
|
2021-11-07 08:06:57 -05:00
|
|
|
|
|
|
|
// Run the server.
|
2021-07-23 15:52:00 -04:00
|
|
|
http_server.run().await
|
2021-07-19 15:16:13 -04:00
|
|
|
}
|