diff --git a/Cargo.lock b/Cargo.lock index 965ac4b..8d3b284 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -254,11 +254,28 @@ dependencies = [ "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ansi_term" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "arc-swap" version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "atty" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "autocfg" version = "0.1.7" @@ -361,12 +378,16 @@ name = "bunbun" version = "0.2.2" dependencies = [ "actix-web 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "handlebars 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "hotwatch 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)", + "simple_logger 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -416,6 +437,20 @@ dependencies = [ "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "clap" +version = "2.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "cloudabi" version = "0.0.3" @@ -424,6 +459,16 @@ dependencies = [ "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "colored" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "const-random" version = "0.1.6" @@ -1426,6 +1471,16 @@ dependencies = [ "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "simple_logger" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "colored 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "slab" version = "0.4.2" @@ -1463,6 +1518,11 @@ dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "strsim" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "syn" version = "0.15.44" @@ -1494,6 +1554,14 @@ dependencies = [ "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "thread_local" version = "0.3.6" @@ -1707,6 +1775,11 @@ dependencies = [ "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "unicode-width" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "unicode-xid" version = "0.1.0" @@ -1737,6 +1810,11 @@ dependencies = [ "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "vec_map" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "walkdir" version = "2.2.9" @@ -1844,7 +1922,9 @@ dependencies = [ "checksum adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2" "checksum ahash 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "6f33b5018f120946c1dcf279194f238a9f146725593ead1c08fa47ff22b0b5d3" "checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d" +"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" "checksum arc-swap 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d7b8a9123b8027467bce0099fe556c628a53c8d83df0507084c31e9ba2e39aff" +"checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90" "checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" "checksum awc 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "5e995283278dd3bf0449e7534e77184adb1570c0de8b6a50bf7c9d01ad8db8c4" "checksum backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)" = "924c76597f0d9ca25d762c25a4d369d51267536465dc5064bdf0eb073ed477ea" @@ -1862,7 +1942,9 @@ dependencies = [ "checksum cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)" = "f52a465a666ca3d838ebbf08b241383421412fe7ebb463527bba275526d89f76" "checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" "checksum chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "31850b4a4d6bae316f7a09e691c944c28299298837edc0a03f755618c23cbc01" +"checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +"checksum colored 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "433e7ac7d511768127ed85b0c4947f47a254131e37864b2dc13f52aa32cd37e5" "checksum const-random 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7b641a8c9867e341f3295564203b1c250eb8ce6cb6126e007941f78c4d2ed7fe" "checksum const-random-macro 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c750ec12b83377637110d5a57f5ae08e895b06c4b16e2bdbf1a94ef717428c59" "checksum copyless 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6ff9c56c9fb2a49c05ef0e431485a22400af20d33226dc0764d891d09e724127" @@ -1982,14 +2064,17 @@ dependencies = [ "checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" "checksum signal-hook 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "7a9c17dd3ba2d36023a5c9472ecddeda07e27fd0b05436e8c1e0c8f178185652" "checksum signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41" +"checksum simple_logger 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3a4756ecc75607ba957820ac0a2413a6c27e6c61191cda0c62c6dcea4da88870" "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" "checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" "checksum smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44e59e0c9fa00817912ae6e4e6e3c4fe04455e75699d06eedc7d85917ed8e8f4" "checksum socket2 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "e8b74de517221a2cb01a53349cf54182acdc31a074727d3079068448c0676d85" "checksum string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d24114bfcceb867ca7f71a0d3fe45d45619ec47a6fbfa98cb14e14250bfa5d6d" +"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" "checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" "checksum syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)" = "dff0acdb207ae2fe6d5976617f887eb1e35a2ba52c13c7234c790960cdad9238" "checksum synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" +"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" "checksum threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865" "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" @@ -2009,10 +2094,12 @@ dependencies = [ "checksum ucd-trie 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8f00ed7be0c1ff1e24f46c3d2af4859f7e863672ba3a6e92e7cff702bf9f06c2" "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" "checksum unicode-normalization 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b561e267b2326bb4cebfc0ef9e68355c7abe6c6f522aeac2f5bf95d56c59bdcf" +"checksum unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" "checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" "checksum url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75b414f6c464c879d7f9babf951f23bc3743fb7313c081b2e6ca719067ea9d61" +"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" "checksum walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9658c94fa8b940eab2250bd5a457f9c48b748420d71293b165c8cdbe2f55f71e" "checksum wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d" "checksum widestring 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "effc0e4ff8085673ea7b9b2e3c73f6bd4d118810c9009ed8f1e16bd96c331db6" diff --git a/Cargo.toml b/Cargo.toml index fe34a4a..847081a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,10 @@ handlebars = "2.0" hotwatch = "0.4" percent-encoding = "2.1" itertools = "0.8" +libc = "0.2" +log = "0.4" +simple_logger = "1.3" +clap = "2.33" [profile.release] lto = true diff --git a/src/main.rs b/src/main.rs index ab8c80a..0bf794e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,9 @@ +use actix_web::middleware::Logger; use actix_web::{App, HttpServer}; use handlebars::Handlebars; use hotwatch::{Event, Hotwatch}; +use libc::daemon; +use log::{debug, error, info, trace, warn}; use serde::Deserialize; use std::collections::HashMap; use std::fmt; @@ -21,6 +24,7 @@ enum BunBunError { IoError(std::io::Error), ParseError(serde_yaml::Error), WatchError(hotwatch::Error), + LoggerInitError(log::SetLoggerError), } impl fmt::Display for BunBunError { @@ -29,6 +33,7 @@ impl fmt::Display for BunBunError { BunBunError::IoError(e) => e.fmt(f), BunBunError::ParseError(e) => e.fmt(f), BunBunError::WatchError(e) => e.fmt(f), + BunBunError::LoggerInitError(e) => e.fmt(f), } } } @@ -48,6 +53,7 @@ macro_rules! from_error { from_error!(std::io::Error, IoError); from_error!(serde_yaml::Error, ParseError); from_error!(hotwatch::Error, WatchError); +from_error!(log::SetLoggerError, LoggerInitError); /// Dynamic variables that either need to be present at runtime, or can be /// changed during runtime. @@ -59,6 +65,9 @@ pub struct State { } fn main() -> Result<(), BunBunError> { + simple_logger::init_with_level(log::Level::Info)?; + // simple_logger::init()?; + let conf = read_config(CONFIG_FILE)?; let renderer = compile_templates(); let state = Arc::from(RwLock::new(State { @@ -73,21 +82,33 @@ fn main() -> Result<(), BunBunError> { watch.watch(CONFIG_FILE, move |e: Event| { if let Event::Write(_) = e { + trace!("Grabbing writer lock on state..."); let mut state = state.write().unwrap(); + trace!("Obtained writer lock on state!"); match read_config(CONFIG_FILE) { Ok(conf) => { state.public_address = conf.public_address; state.default_route = conf.default_route; state.routes = conf.routes; + info!("Successfully updated active state"); } - Err(e) => eprintln!("Config is malformed: {}", e), + Err(e) => warn!("Failed to update config file: {}", e), } + } else { + debug!("Saw event {:#?} but ignored it", e); } })?; + info!("Watcher is now watching {}", CONFIG_FILE); + + // unsafe { + // daemon(0, 0); + // } + HttpServer::new(move || { App::new() .data(state_ref.clone()) + .wrap(Logger::default()) .service(routes::hop) .service(routes::list) .service(routes::index) @@ -110,19 +131,30 @@ struct Config { /// Attempts to read the config file. If it doesn't exist, generate one a /// default config file before attempting to parse it. fn read_config(config_file_path: &str) -> Result { + trace!("Loading config file..."); let config_str = match read_to_string(config_file_path) { - Ok(conf_str) => conf_str, + Ok(conf_str) => { + debug!("Successfully loaded config file into memory."); + conf_str + } Err(_) => { - eprintln!( + info!( "Unable to find a {} file. Creating default!", config_file_path ); - let mut fd = OpenOptions::new() + + let fd = OpenOptions::new() .write(true) .create_new(true) - .open(config_file_path) - .expect("Unable to write to directory!"); - fd.write_all(DEFAULT_CONFIG)?; + .open(config_file_path); + + match fd { + Ok(mut fd) => fd.write_all(DEFAULT_CONFIG)?, + Err(e) => { + error!("Failed to write to {}: {}. Default config will be loaded but not saved.", config_file_path, e); + } + }; + String::from_utf8_lossy(DEFAULT_CONFIG).into_owned() } }; @@ -147,6 +179,7 @@ fn compile_templates() -> Handlebars { include_bytes!(concat!("templates/", $template, ".hbs"))) ) .unwrap(); + debug!("Loaded {} template.", $template); )* }; } diff --git a/src/routes.rs b/src/routes.rs index 86a7eff..beb9289 100644 --- a/src/routes.rs +++ b/src/routes.rs @@ -5,6 +5,7 @@ use actix_web::http::header; use actix_web::web::{Data, Query}; use actix_web::{HttpResponse, Responder}; use itertools::Itertools; +use log::debug; use percent_encoding::{utf8_percent_encode, AsciiSet, CONTROLS}; use serde::Deserialize; use std::collections::HashMap; @@ -70,7 +71,10 @@ fn resolve_hop( let mut split_args = query.split_ascii_whitespace().peekable(); let command = match split_args.peek() { Some(command) => command, - None => return (None, String::new()), + None => { + debug!("Found empty query, returning no route."); + return (None, String::new()); + } }; match (routes.get(*command), default_route) { @@ -79,14 +83,28 @@ fn resolve_hop( Some(resolved.clone()), match split_args.next() { // Discard the first result, we found the route using the first arg - Some(_) => split_args.join(" "), - None => String::new(), + Some(_) => { + let args = split_args.join(" "); + debug!("Resolved {} with args {}", resolved, args); + args + } + None => { + debug!("Resolved {} with no args", resolved); + String::new() + } }, ), // Unable to find route, but had a default route - (None, Some(route)) => (routes.get(route).cloned(), split_args.join(" ")), + (None, Some(route)) => { + let args = split_args.join(" "); + debug!("Using default route {} with args {}", route, args); + (routes.get(route).cloned(), args) + } // No default route and no match - (None, None) => (None, String::new()), + (None, None) => { + debug!("Failed to resolve route!"); + (None, String::new()) + } } }