use actix_web::http::header::HeaderName;
use limitation_proxy::app::Config;
use std::net::SocketAddr;
use std::num::ParseIntError;
use std::time::Duration;
use structopt::{clap, StructOpt};
use url::Url;
const DEFAULT_CLI_BIND: &str = "0.0.0.0:8080";
const DEFAULT_CLI_HEADER: &str = "authorization";
const DEFAULT_CLI_LIMIT: &str = "5000";
const DEFAULT_CLI_PERIOD_SECS: &str = "3600";
const DEFAULT_CLI_PROXY: &str = "http://127.0.0.1:8000";
const DEFAULT_CLI_REDIS: &str = "redis://127.0.0.1/";
const AUTHOR: &str = concat!(env!("CARGO_PKG_AUTHORS"), "\n\n");
pub(crate) fn from_args() -> Args {
Args::from_args()
}
#[derive(Debug, StructOpt)]
#[structopt(
global_settings(&[clap::AppSettings::UnifiedHelpMessage]),
max_term_width = 80,
author = AUTHOR,
)]
pub(crate) struct Args {
#[structopt(
short = "b",
long = "bind",
env = "BIND_ADDR",
hide_env_values = true,
rename_all = "screaming_snake_case",
default_value = DEFAULT_CLI_BIND
)]
pub(crate) bind: SocketAddr,
#[structopt(
short = "H",
long = "header",
rename_all = "screaming_snake_case",
default_value = DEFAULT_CLI_HEADER
)]
pub(crate) header: HeaderName,
#[structopt(
short = "l",
long = "limit",
rename_all = "screaming_snake_case",
default_value = DEFAULT_CLI_LIMIT
)]
pub(crate) limit: usize,
#[structopt(
short = "P",
long = "period",
rename_all = "screaming_snake_case",
parse(try_from_str = parse_period),
default_value = DEFAULT_CLI_PERIOD_SECS
)]
pub(crate) period: Duration,
#[structopt(
short = "p",
long = "proxy",
env = "PROXY_URL",
hide_env_values = true,
rename_all = "screaming_snake_case",
default_value = DEFAULT_CLI_PROXY
)]
pub(crate) proxy: Url,
#[structopt(
short = "r",
long = "redis",
env = "REDIS_URL",
hide_env_values = true,
rename_all = "screaming_snake_case",
default_value = DEFAULT_CLI_REDIS
)]
pub(crate) redis: Url,
}
fn parse_period(src: &str) -> Result<Duration, ParseIntError> {
Ok(Duration::from_secs(u64::from_str_radix(src, 16)?))
}
impl From<Args> for Config {
fn from(args: Args) -> Self {
Config::builder()
.bind_addr(args.bind)
.redis_url(args.redis)
.proxy_to(args.proxy)
.header(args.header)
.rate_limit(args.limit)
.rate_period(args.period)
.build()
}
}
pub(crate) mod util {
use std::env;
pub(crate) fn init_logger() {
if env::var("RUST_LOG").is_err() {
env::set_var(
"RUST_LOG",
concat!(
"actix_server=info,actix_web=info,",
env!("CARGO_PKG_NAME"),
"=info"
),
);
}
env_logger::init();
}
}