index : static-web-server.git

ascending towards madness

author Mac Chaffee <me@macchaffee.com> 2023-06-01 19:45:58.0 +00:00:00
committer GitHub <noreply@github.com> 2023-06-01 19:45:58.0 +00:00:00
commit
4e01de60e7521fe6fe4c9eae5fcb00cf1988d6f5 [patch]
tree
ed84b67ab1e60eadbab608f233073d2583062f0f
parent
b685cda8c590f90b51899ffee281be01a098b2f3
download
4e01de60e7521fe6fe4c9eae5fcb00cf1988d6f5.tar.gz

refactor: migrate from structopt to clap v3 (#211)

* Migrate from structopt to clap v3

Essentially followed this guide: https://github.com/clap-rs/clap/blob/v3.1.6/CHANGELOG.md#migrating
* Depend on clap directly
* Update use statements
* Change "short" params to single chars
* required_if -> required_if_eq
* When referencing other args like in required_if_eq, use hyphens instead of dashes
* Last param of default_value_if is now an Option
* refactor: https-redirect* cli options

---------

Signed-off-by: Mac Chaffee <me@macchaffee.com>
Co-authored-by: Jose Quintana <joseluisquintana20@gmail.com>

Diff

 Cargo.lock               | 126 ++++++++++++++++++++++++++++++------------------
 Cargo.toml               |   2 +-
 src/directory_listing.rs |   2 +-
 src/settings/cli.rs      |  64 ++++++++++++------------
 src/settings/mod.rs      |   2 +-
 5 files changed, 117 insertions(+), 79 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index da52844..1b19c2e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -79,6 +79,17 @@ dependencies = [
]

[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
 "hermit-abi 0.1.19",
 "libc",
 "winapi",
]

[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -222,13 +233,41 @@ dependencies = [

[[package]]
name = "clap"
version = "2.34.0"
version = "3.2.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123"
dependencies = [
 "atty",
 "bitflags",
 "clap_derive",
 "clap_lex",
 "indexmap",
 "once_cell",
 "strsim",
 "termcolor",
 "textwrap",
 "unicode-width",
]

[[package]]
name = "clap_derive"
version = "3.2.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae6371b8bdc8b7d3959e9cf7b22d4435ef3e79e138688421ec654acf8c81b008"
dependencies = [
 "heck",
 "proc-macro-error",
 "proc-macro2",
 "quote",
 "syn 1.0.109",
]

[[package]]
name = "clap_lex"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5"
dependencies = [
 "os_str_bytes",
]

[[package]]
@@ -434,11 +473,17 @@ dependencies = [

[[package]]
name = "heck"
version = "0.3.3"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"

[[package]]
name = "hermit-abi"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
dependencies = [
 "unicode-segmentation",
 "libc",
]

[[package]]
@@ -714,7 +759,7 @@ version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
dependencies = [
 "hermit-abi",
 "hermit-abi 0.2.6",
 "libc",
]

@@ -725,6 +770,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9670a07f94779e00908f3e686eab508878ebb390ba6e604d3a284c00e8d0487b"

[[package]]
name = "os_str_bytes"
version = "6.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ceedf44fb00f2d1984b0bc98102627ce622e083e49a5bacdb3e514fa4238e267"

[[package]]
name = "overload"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1076,6 +1127,7 @@ dependencies = [
 "bcrypt",
 "bytes",
 "chrono",
 "clap",
 "form_urlencoded",
 "futures-util",
 "globset",
@@ -1096,7 +1148,6 @@ dependencies = [
 "serde_repr",
 "signal-hook",
 "signal-hook-tokio",
 "structopt",
 "tikv-jemallocator",
 "tokio",
 "tokio-rustls",
@@ -1108,28 +1159,10 @@ dependencies = [
]

[[package]]
name = "structopt"
version = "0.3.26"
name = "strsim"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10"
dependencies = [
 "clap",
 "lazy_static",
 "structopt-derive",
]

[[package]]
name = "structopt-derive"
version = "0.4.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0"
dependencies = [
 "heck",
 "proc-macro-error",
 "proc-macro2",
 "quote",
 "syn 1.0.109",
]
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"

[[package]]
name = "subtle"
@@ -1160,15 +1193,21 @@ dependencies = [
]

[[package]]
name = "textwrap"
version = "0.11.0"
name = "termcolor"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"
dependencies = [
 "unicode-width",
 "winapi-util",
]

[[package]]
name = "textwrap"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d"

[[package]]
name = "thread_local"
version = "1.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1341,18 +1380,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0"

[[package]]
name = "unicode-segmentation"
version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"

[[package]]
name = "unicode-width"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"

[[package]]
name = "untrusted"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1479,6 +1506,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"

[[package]]
name = "winapi-util"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
dependencies = [
 "winapi",
]

[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 5a2c847..3387d6e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -70,7 +70,7 @@ rustls-pemfile = { version = "1.0", optional = true }
serde = { version = "1.0", default-features = false, features = ["derive"] }
serde_ignored = "0.1"
serde_repr = "0.1"
structopt = { version = "0.3", default-features = false }
clap = { version = "3.0", features = ["derive", "env"] }
chrono = { version = "0.4", default-features = false, features = ["std", "clock"] }
tokio = { version = "1", default-features = false, features = ["rt-multi-thread", "macros", "fs", "io-util", "signal"] }
tokio-rustls = { version = "0.24", optional = true }
diff --git a/src/directory_listing.rs b/src/directory_listing.rs
index 47753a1..952db87 100644
--- a/src/directory_listing.rs
+++ b/src/directory_listing.rs
@@ -9,6 +9,7 @@
#![allow(missing_docs)]

use chrono::{DateTime, Local, NaiveDateTime, Utc};
use clap::arg_enum;
use futures_util::future::Either;
use futures_util::{future, FutureExt};
use headers::{ContentLength, ContentType, HeaderMapExt};
@@ -21,7 +22,6 @@ use std::future::Future;
use std::io;
use std::path::Path;
use std::time::{SystemTime, UNIX_EPOCH};
use structopt::clap::arg_enum;

use crate::{exts::http::MethodExt, Context, Result};

diff --git a/src/settings/cli.rs b/src/settings/cli.rs
index 2c686d9..fc41286 100644
--- a/src/settings/cli.rs
+++ b/src/settings/cli.rs
@@ -5,8 +5,8 @@

//! The server CLI options

use clap::StructOpt;
use std::path::PathBuf;
use structopt::StructOpt;

use crate::directory_listing::DirListFmt;

@@ -14,19 +14,19 @@ use crate::directory_listing::DirListFmt;
#[derive(Debug, StructOpt)]
#[structopt(about, author)]
pub struct General {
    #[structopt(long, short = "a", default_value = "::", env = "SERVER_HOST")]
    #[structopt(long, short = 'a', default_value = "::", env = "SERVER_HOST")]
    /// Host address (E.g 127.0.0.1 or ::1)
    pub host: String,

    #[structopt(long, short = "p", default_value = "80", env = "SERVER_PORT")]
    #[structopt(long, short = 'p', default_value = "80", env = "SERVER_PORT")]
    /// Host port
    pub port: u16,

    #[structopt(
        long,
        short = "f",
        short = 'f',
        env = "SERVER_LISTEN_FD",
        conflicts_with_all(&["host", "port", "https_redirect"])
        conflicts_with_all(&["host", "port", "https-redirect"])
    )]
    /// Instead of binding to a TCP port, accept incoming connections to an already-bound TCP
    /// socket listener on the specified file descriptor number (usually zero). Requires that the
@@ -41,7 +41,7 @@ pub struct General {
        not(wasm),
        structopt(
            long,
            short = "n",
            short = 'n',
            default_value = "1",
            env = "SERVER_THREADS_MULTIPLIER"
        )
@@ -50,7 +50,7 @@ pub struct General {
        wasm,
        structopt(
            long,
            short = "n",
            short = 'n',
            default_value = "2",
            env = "SERVER_THREADS_MULTIPLIER"
        )
@@ -65,7 +65,7 @@ pub struct General {
        not(wasm),
        structopt(
            long,
            short = "b",
            short = 'b',
            default_value = "512",
            env = "SERVER_MAX_BLOCKING_THREADS"
        )
@@ -74,7 +74,7 @@ pub struct General {
        wasm,
        structopt(
            long,
            short = "b",
            short = 'b',
            default_value = "20",
            env = "SERVER_MAX_BLOCKING_THREADS"
        )
@@ -82,7 +82,7 @@ pub struct General {
    /// Maximum number of blocking threads
    pub max_blocking_threads: usize,

    #[structopt(long, short = "d", default_value = "./public", env = "SERVER_ROOT")]
    #[structopt(long, short = 'd', default_value = "./public", env = "SERVER_ROOT")]
    /// Root directory path of static files.
    pub root: PathBuf,

@@ -106,13 +106,13 @@ pub struct General {
    /// HTML file path that is used for GET requests when the requested path doesn't exist. The fallback page is served with a 200 status code, useful when using client routers. If the path is not specified or simply doesn't exist then this feature will not be active.
    pub page_fallback: Option<PathBuf>,

    #[structopt(long, short = "g", default_value = "error", env = "SERVER_LOG_LEVEL")]
    #[structopt(long, short = 'g', default_value = "error", env = "SERVER_LOG_LEVEL")]
    /// Specify a logging level in lower case. Values: error, warn, info, debug or trace
    pub log_level: String,

    #[structopt(
        long,
        short = "c",
        short = 'c',
        default_value = "",
        env = "SERVER_CORS_ALLOW_ORIGINS"
    )]
@@ -121,7 +121,7 @@ pub struct General {

    #[structopt(
        long,
        short = "j",
        short = 'j',
        default_value = "origin, content-type",
        env = "SERVER_CORS_ALLOW_HEADERS"
    )]
@@ -138,7 +138,7 @@ pub struct General {

    #[structopt(
        long,
        short = "t",
        short = 't',
        parse(try_from_str),
        default_value = "false",
        env = "SERVER_HTTP2_TLS"
@@ -148,13 +148,13 @@ pub struct General {
    /// Enable HTTP/2 with TLS support.
    pub http2: bool,

    #[structopt(long, required_if("http2", "true"), env = "SERVER_HTTP2_TLS_CERT")]
    #[structopt(long, required_if_eq("http2", "true"), env = "SERVER_HTTP2_TLS_CERT")]
    #[cfg(feature = "http2")]
    #[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
    /// Specify the file path to read the certificate.
    pub http2_tls_cert: Option<PathBuf>,

    #[structopt(long, required_if("http2", "true"), env = "SERVER_HTTP2_TLS_KEY")]
    #[structopt(long, required_if_eq("http2", "true"), env = "SERVER_HTTP2_TLS_KEY")]
    #[cfg(feature = "http2")]
    #[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
    /// Specify the file path to read the private key.
@@ -162,42 +162,46 @@ pub struct General {

    #[structopt(
        long,
        required_if("http2", "true"),
        requires_if("true", "http2"),
        parse(try_from_str),
        default_value = "false",
        env = "SERVER_HTTPS_REDIRECT"
    )]
    #[cfg(feature = "http2")]
    #[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
    /// Redirect all requests with scheme "http" to "https" for the current server instance. It depends on "http2" to be enabled.
    pub https_redirect: bool,

    #[structopt(
        long,
        required_if("https_redirect", "true"),
        requires_if("true", "https-redirect"),
        default_value = "localhost",
        env = "HTTPS_REDIRECT_HOST"
    )]
    #[cfg(feature = "http2")]
    #[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
    /// Canonical host name or IP of the HTTPS (HTTPS/2) server. It depends on "https_redirect" to be enabled.
    pub https_redirect_host: String,

    #[structopt(
        long,
        required_if("https_redirect", "true"),
        requires_if("true", "https-redirect"),
        default_value = "80",
        env = "HTTPS_REDIRECT_FROM_PORT"
    )]
    #[cfg(feature = "http2")]
    #[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
    /// HTTP host port where the redirect server will listen for requests to redirect them to HTTPS. It depends on "https_redirect" to be enabled.
    pub https_redirect_from_port: u16,

    #[structopt(
        long,
        required_if("https_redirect", "true"),
        requires_if("true", "https-redirect"),
        default_value = "localhost",
        env = "HTTPS_REDIRECT_FROM_HOSTS"
    )]
    #[cfg(feature = "http2")]
    #[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
    /// List of host names or IPs allowed to redirect from. HTTP requests must contain the HTTP 'Host' header and match against this list. It depends on "https_redirect" to be enabled.
    pub https_redirect_from_hosts: String,

@@ -205,7 +209,7 @@ pub struct General {
    #[cfg_attr(docsrs, doc(cfg(feature = "compression")))]
    #[structopt(
        long,
        short = "x",
        short = 'x',
        parse(try_from_str),
        default_value = "true",
        env = "SERVER_COMPRESSION"
@@ -227,7 +231,7 @@ pub struct General {

    #[structopt(
        long,
        short = "z",
        short = 'z',
        parse(try_from_str),
        default_value = "false",
        env = "SERVER_DIRECTORY_LISTING"
@@ -237,7 +241,7 @@ pub struct General {

    #[structopt(
        long,
        required_if("directory_listing", "true"),
        required_if_eq("directory-listing", "true"),
        default_value = "6",
        env = "SERVER_DIRECTORY_LISTING_ORDER"
    )]
@@ -246,8 +250,7 @@ pub struct General {

    #[structopt(
        long,
        required_if("directory_listing", "true"),
        possible_values = &DirListFmt::variants(),
        required_if_eq("directory-listing", "true"),
        default_value = "html",
        env = "SERVER_DIRECTORY_LISTING_FORMAT",
        case_insensitive = true
@@ -258,8 +261,7 @@ pub struct General {
    #[structopt(
        long,
        parse(try_from_str),
        required_if("http2", "true"),
        default_value_if("http2", Some("true"), "true"),
        default_value_if("http2", Some("true"), Some("true")),
        default_value = "false",
        env = "SERVER_SECURITY_HEADERS"
    )]
@@ -270,7 +272,7 @@ pub struct General {

    #[structopt(
        long,
        short = "e",
        short = 'e',
        parse(try_from_str),
        default_value = "true",
        env = "SERVER_CACHE_CONTROL_HEADERS"
@@ -282,11 +284,11 @@ pub struct General {
    #[structopt(long, default_value = "", env = "SERVER_BASIC_AUTH")]
    pub basic_auth: String,

    #[structopt(long, short = "q", default_value = "0", env = "SERVER_GRACE_PERIOD")]
    #[structopt(long, short = 'q', default_value = "0", env = "SERVER_GRACE_PERIOD")]
    /// Defines a grace period in seconds after a `SIGTERM` signal is caught which will delay the server before to shut it down gracefully. The maximum value is 255 seconds.
    pub grace_period: u8,

    #[structopt(long, short = "w", env = "SERVER_CONFIG_FILE")]
    #[structopt(long, short = 'w', env = "SERVER_CONFIG_FILE")]
    /// Server TOML configuration file path.
    pub config_file: Option<PathBuf>,

@@ -323,7 +325,7 @@ pub struct General {
    #[cfg(windows)]
    #[structopt(
        long,
        short = "s",
        short = 's',
        parse(try_from_str),
        default_value = "false",
        env = "SERVER_WINDOWS_SERVICE"
diff --git a/src/settings/mod.rs b/src/settings/mod.rs
index 51cacaf..bf94bd8 100644
--- a/src/settings/mod.rs
+++ b/src/settings/mod.rs
@@ -6,10 +6,10 @@
//! Module that provides all settings of SWS.
//!

use clap::StructOpt;
use globset::{Glob, GlobMatcher};
use headers::HeaderMap;
use hyper::StatusCode;
use structopt::StructOpt;

use crate::{Context, Result};