use slog::{DrainExt, Level, LevelFilter, Logger, duplicate};
use slog_stream::async_stream;
use slog_term::{self, ColorDecorator, Format, FormatMode, timestamp_utc};
use std::env;
use std::fs::{self, OpenOptions};
use url::Url;
pub const DOT_DIR: &'static str = ".twisty";
#[derive(Clone, Debug)]
pub struct Config {
host: String,
port: u16,
tls_enabled: bool,
host_header: String,
origin_header: String,
path: String,
query: String,
pfx_file_path: String,
dual: Logger,
}
impl Config {
pub fn new(url: Url) -> Result<Config, ()> {
let stderr_term = slog_term::streamer().stderr().async().compact().build();
let stderr_drain = LevelFilter::new(stderr_term, Level::Error);
let mut logpath = env::temp_dir();
logpath.push(DOT_DIR);
if fs::create_dir_all(&logpath).is_err() {
logpath.pop();
}
logpath.push("twisty.log");
let mut file_drain = None;
if let Ok(log_file) = OpenOptions::new().create(true).append(true).open(logpath) {
let fmt = Format::new(FormatMode::Compact,
ColorDecorator::new_colored(),
Box::new(timestamp_utc));
file_drain = Some(async_stream(log_file, fmt));
}
let dual = if let Some(file_drain) = file_drain {
Logger::root(duplicate(file_drain, stderr_drain).fuse(),
o!(
"executable" => env!("CARGO_PKG_NAME"),
"version" => env!("CARGO_PKG_VERSION")
))
} else {
Logger::root(stderr_drain.fuse(),
o!(
"executable" => env!("CARGO_PKG_NAME"),
"version" => env!("CARGO_PKG_VERSION")
))
};
let scheme = url.scheme();
if !(scheme == "ws" || scheme == "wss") {
err!("invalid websocket scheme: {}", scheme);
return Err(());
}
let host = if let Some(host_str) = url.host_str() {
host_str.into()
} else {
"127.0.0.1".into()
};
let port = if let Some(port) = url.port() {
port
} else if scheme == "ws" {
80
} else if scheme == "wss" {
443
} else {
return Err(());
};
let path = url.path().to_string();
let query = if let Some(query) = url.query() {
query.to_string()
} else {
String::new()
};
Ok(Config {
host: host,
port: port,
tls_enabled: scheme == "wss",
host_header: String::from("jasonozias.com"),
origin_header: String::from("http://jasonozias.com"),
path: path,
query: query,
pfx_file_path: String::from(".env/jasonozias.com.pfx"),
dual: dual,
})
}
pub fn host(&self) -> &str {
&self.host
}
pub fn port(&self) -> u16 {
self.port
}
pub fn tls_enabled(&self) -> bool {
self.tls_enabled
}
pub fn host_header(&self) -> &str {
&self.host_header
}
pub fn set_host_header(&mut self, host_header: String) -> &mut Config {
self.host_header = host_header;
self
}
pub fn origin_header(&self) -> &str {
&self.origin_header
}
pub fn set_origin_header(&mut self, origin_header: String) -> &mut Config {
self.origin_header = origin_header;
self
}
pub fn path(&self) -> &str {
&self.path
}
pub fn query(&self) -> &str {
&self.query
}
#[allow(dead_code)]
pub fn pfx_file_path(&self) -> &str {
&self.pfx_file_path
}
pub fn set_pfx_file_path(&mut self, pfx_file_path: String) -> &mut Config {
self.pfx_file_path = pfx_file_path;
self
}
pub fn dual(&self) -> Logger {
self.dual.clone()
}
}