use clap::Parser;
use std::path::PathBuf;
#[cfg(feature = "directory-listing")]
use crate::directory_listing::DirListFmt;
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
pub struct General {
#[arg(long, short = 'a', default_value = "::", env = "SERVER_HOST")]
pub host: String,
#[arg(long, short = 'p', default_value = "80", env = "SERVER_PORT")]
pub port: u16,
#[cfg_attr(
feature = "http2",
arg(
long,
short = 'f',
env = "SERVER_LISTEN_FD",
conflicts_with_all(&["host", "port", "https_redirect"])
)
)]
#[cfg_attr(
not(feature = "http2"),
arg(
long,
short = 'f',
env = "SERVER_LISTEN_FD",
conflicts_with_all(&["host", "port"])
)
)]
pub fd: Option<usize>,
#[cfg_attr(
not(wasm),
arg(
long,
short = 'n',
default_value = "1",
env = "SERVER_THREADS_MULTIPLIER"
)
)]
#[cfg_attr(
wasm,
arg(
long,
short = 'n',
default_value = "2",
env = "SERVER_THREADS_MULTIPLIER"
)
)]
pub threads_multiplier: usize,
#[cfg_attr(
not(wasm),
arg(
long,
short = 'b',
default_value = "512",
env = "SERVER_MAX_BLOCKING_THREADS"
)
)]
#[cfg_attr(
wasm,
arg(
long,
short = 'b',
default_value = "20",
env = "SERVER_MAX_BLOCKING_THREADS"
)
)]
pub max_blocking_threads: usize,
#[arg(long, short = 'd', default_value = "./public", env = "SERVER_ROOT")]
pub root: PathBuf,
#[arg(
long,
default_value = "./public/50x.html",
env = "SERVER_ERROR_PAGE_50X"
)]
pub page50x: PathBuf,
#[arg(
long,
default_value = "./public/404.html",
env = "SERVER_ERROR_PAGE_404"
)]
pub page404: PathBuf,
#[cfg(feature = "fallback-page")]
#[cfg_attr(docsrs, doc(cfg(feature = "fallback-page")))]
#[arg(long, default_value = "", value_parser = value_parser_pathbuf, env = "SERVER_FALLBACK_PAGE")]
pub page_fallback: PathBuf,
#[arg(long, short = 'g', default_value = "error", env = "SERVER_LOG_LEVEL")]
pub log_level: String,
#[arg(
long,
short = 'c',
default_value = "",
env = "SERVER_CORS_ALLOW_ORIGINS"
)]
pub cors_allow_origins: String,
#[arg(
long,
short = 'j',
default_value = "origin, content-type",
env = "SERVER_CORS_ALLOW_HEADERS"
)]
pub cors_allow_headers: String,
#[arg(
long,
default_value = "origin, content-type",
env = "SERVER_CORS_EXPOSE_HEADERS"
)]
pub cors_expose_headers: String,
#[arg(
long,
short = 't',
default_value = "false",
default_missing_value("true"),
num_args(0..=1),
require_equals(true),
action = clap::ArgAction::Set,
env = "SERVER_HTTP2_TLS",
)]
#[cfg(feature = "http2")]
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
pub http2: bool,
#[arg(long, required_if_eq("http2", "true"), env = "SERVER_HTTP2_TLS_CERT")]
#[cfg(feature = "http2")]
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
pub http2_tls_cert: Option<PathBuf>,
#[arg(long, required_if_eq("http2", "true"), env = "SERVER_HTTP2_TLS_KEY")]
#[cfg(feature = "http2")]
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
pub http2_tls_key: Option<PathBuf>,
#[arg(
long,
default_value = "false",
default_missing_value("true"),
num_args(0..=1),
require_equals(true),
action = clap::ArgAction::Set,
requires_if("true", "http2"),
env = "SERVER_HTTPS_REDIRECT"
)]
#[cfg(feature = "http2")]
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
pub https_redirect: bool,
#[arg(
long,
requires_if("true", "https_redirect"),
default_value = "localhost",
env = "SERVER_HTTPS_REDIRECT_HOST"
)]
#[cfg(feature = "http2")]
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
pub https_redirect_host: String,
#[arg(
long,
requires_if("true", "https_redirect"),
default_value = "80",
env = "SERVER_HTTPS_REDIRECT_FROM_PORT"
)]
#[cfg(feature = "http2")]
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
pub https_redirect_from_port: u16,
#[arg(
long,
requires_if("true", "https_redirect"),
default_value = "localhost",
env = "SERVER_HTTPS_REDIRECT_FROM_HOSTS"
)]
#[cfg(feature = "http2")]
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
pub https_redirect_from_hosts: String,
#[arg(long, default_value = "index.html", env = "SERVER_INDEX_FILES")]
pub index_files: String,
#[cfg(feature = "compression")]
#[cfg_attr(docsrs, doc(cfg(feature = "compression")))]
#[arg(
long,
short = 'x',
default_value = "true",
default_missing_value("true"),
num_args(0..=1),
require_equals(true),
action = clap::ArgAction::Set,
env = "SERVER_COMPRESSION",
)]
pub compression: bool,
#[cfg(feature = "compression")]
#[cfg_attr(docsrs, doc(cfg(feature = "compression")))]
#[arg(
long,
default_value = "false",
default_missing_value("true"),
num_args(0..=1),
require_equals(true),
action = clap::ArgAction::Set,
env = "SERVER_COMPRESSION_STATIC",
)]
pub compression_static: bool,
#[cfg(feature = "directory-listing")]
#[cfg_attr(docsrs, doc(cfg(feature = "directory-listing")))]
#[arg(
long,
short = 'z',
default_value = "false",
default_missing_value("true"),
num_args(0..=1),
require_equals(true),
action = clap::ArgAction::Set,
env = "SERVER_DIRECTORY_LISTING",
)]
pub directory_listing: bool,
#[cfg(feature = "directory-listing")]
#[cfg_attr(docsrs, doc(cfg(feature = "directory-listing")))]
#[arg(
long,
requires_if("true", "directory_listing"),
default_value = "6",
env = "SERVER_DIRECTORY_LISTING_ORDER"
)]
pub directory_listing_order: u8,
#[cfg(feature = "directory-listing")]
#[cfg_attr(docsrs, doc(cfg(feature = "directory-listing")))]
#[arg(
long,
value_enum,
requires_if("true", "directory_listing"),
default_value = "html",
env = "SERVER_DIRECTORY_LISTING_FORMAT",
ignore_case(true)
)]
pub directory_listing_format: DirListFmt,
#[arg(
long,
default_value = "false",
default_value_if("http2", "true", Some("true")),
default_missing_value("true"),
num_args(0..=1),
require_equals(true),
action = clap::ArgAction::Set,
env = "SERVER_SECURITY_HEADERS",
)]
pub security_headers: bool,
#[arg(
long,
short = 'e',
default_value = "true",
env = "SERVER_CACHE_CONTROL_HEADERS"
)]
#[arg(
long,
short = 'e',
default_value = "true",
default_missing_value("true"),
num_args(0..=1),
require_equals(true),
action = clap::ArgAction::Set,
env = "SERVER_CACHE_CONTROL_HEADERS",
)]
pub cache_control_headers: bool,
#[cfg(feature = "basic-auth")]
#[arg(long, default_value = "", env = "SERVER_BASIC_AUTH")]
pub basic_auth: String,
#[arg(long, short = 'q', default_value = "0", env = "SERVER_GRACE_PERIOD")]
pub grace_period: u8,
#[arg(long, short = 'w', env = "SERVER_CONFIG_FILE")]
pub config_file: Option<PathBuf>,
#[arg(
long,
default_value = "false",
default_missing_value("true"),
num_args(0..=1),
require_equals(true),
action = clap::ArgAction::Set,
env = "SERVER_LOG_REMOTE_ADDRESS",
)]
pub log_remote_address: bool,
#[arg(
long,
default_value = "true",
default_missing_value("true"),
num_args(0..=1),
require_equals(true),
action = clap::ArgAction::Set,
env = "SERVER_REDIRECT_TRAILING_SLASH",
)]
pub redirect_trailing_slash: bool,
#[arg(
long,
default_value = "false",
default_missing_value("true"),
num_args(0..=1),
require_equals(true),
action = clap::ArgAction::Set,
env = "SERVER_IGNORE_HIDDEN_FILES",
)]
pub ignore_hidden_files: bool,
#[arg(
long,
default_value = "false",
default_missing_value("true"),
num_args(0..=1),
require_equals(true),
action = clap::ArgAction::Set,
env = "SERVER_HEALTH",
)]
pub health: bool,
#[cfg(windows)]
#[arg(
long,
short = 's',
default_value = "false",
default_missing_value("true"),
num_args(0..=1),
require_equals(true),
action = clap::ArgAction::Set,
env = "SERVER_WINDOWS_SERVICE",
)]
pub windows_service: bool,
#[cfg(windows)]
#[command(subcommand)]
pub commands: Option<Commands>,
}
#[cfg(windows)]
#[derive(Debug, clap::Subcommand)]
pub enum Commands {
#[command(name = "install")]
Install {},
#[command(name = "uninstall")]
Uninstall {},
}
#[cfg(feature = "fallback-page")]
fn value_parser_pathbuf(s: &str) -> crate::Result<PathBuf, String> {
Ok(PathBuf::from(s))
}