index : static-web-server.git

ascending towards madness

author Jose Quintana <1700322+joseluisq@users.noreply.github.com> 2024-02-12 22:19:15.0 +00:00:00
committer GitHub <noreply@github.com> 2024-02-12 22:19:15.0 +00:00:00
commit
1a6caa476ac4adce1ad015a08baf9440bea4dbba [patch]
tree
6b2b71f4bdfa460d84c7d961fbe5ba0d65074754
parent
a3e5050ab61e3be829ab63aa3cdfd0f673202838
download
1a6caa476ac4adce1ad015a08baf9440bea4dbba.tar.gz

feat: add `all` and `experimental` Cargo feature flags (#313)

* feat: `all` and `experimental` cargo feature flags
  - the `all` will host all available features (`default`) plus the
    `experimental`.
  - the `experimental` will only hold unstable features like for example
    `metrics` (as of writing)
* chore: enable the `all` cargo feature for freebsd

this feature also fixes #312

Diff

 .cargo/config.toml                         |  2 +-
 .cirrus.yml                                |  8 +++++---
 .github/workflows/devel.yml                |  6 ++++--
 .github/workflows/release.build.manual.yml |  6 +++++-
 .github/workflows/release.yml              |  4 +++-
 Cargo.toml                                 |  8 ++++++--
 docs/content/building-from-source.md       | 20 +++++++++++++++++++-
 src/handler.rs                             |  8 ++++----
 src/server.rs                              |  8 ++++----
 src/settings/cli.rs                        |  2 +-
 src/settings/file.rs                       |  2 +-
 src/settings/mod.rs                        |  7 ++++---
 src/testing.rs                             |  2 +-
 tests/experimental_metrics.rs              |  2 +-
 14 files changed, 59 insertions(+), 26 deletions(-)

diff --git a/.cargo/config.toml b/.cargo/config.toml
index a89bcf2..c13d6c3 100644
--- a/.cargo/config.toml
+++ b/.cargo/config.toml
@@ -10,7 +10,7 @@ rustflags = ["-C", "target-feature=+crt-static"]
[target.i686-pc-windows-msvc]
rustflags = ["-C", "link-arg=libvcruntime.lib"]

# Required for RuntimeMetrics as of writing
[build]
# Required for experimental features like `metrics` and others.
rustflags = ["--cfg", "tokio_unstable"]
rustdocflags = ["--cfg", "tokio_unstable"] 
diff --git a/.cirrus.yml b/.cirrus.yml
index 85adc05..438e6b2 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -9,6 +9,7 @@ task:
  only_if: $CIRRUS_TAG == ''
  env:
    RUSTFLAGS: -Dwarnings --cfg tokio_unstable
    CARGO_FEATURES: "--features=all"
  matrix:
    - name: freebsd-amd64-test
      env:
@@ -32,17 +33,18 @@ task:
  test_script:
    - . $HOME/.cargo/env
    - |
      cargo test --all --target="$BINARY_ARCH-unknown-freebsd"
      cargo test --all --target="$BINARY_ARCH-unknown-freebsd" $CARGO_FEATURES
  build_test_script:
    - . $HOME/.cargo/env
    - |
      cargo rustc --bin static-web-server --verbose --target="$BINARY_ARCH-unknown-freebsd"
      cargo build --bin static-web-server -vv --target="$BINARY_ARCH-unknown-freebsd" $CARGO_FEATURES
      target/$BINARY_ARCH-unknown-freebsd/debug/static-web-server -h

task:
  only_if: $CIRRUS_TAG != ''
  env:
    RUSTFLAGS: -Dwarnings --cfg tokio_unstable
    CARGO_FEATURES: "--features=all"
    GITHUB_TOKEN: ENCRYPTED[d1766ef328d83729917d2ffb875d64c35d1c0177edf8f32e66ec464daf5c1b7b145d65fc6c044a73fffe2235d3b38349]
  matrix:
    - name: freebsd-amd64-release
@@ -66,7 +68,7 @@ task:
    - rustup show
  build_script: |
    . $HOME/.cargo/env
    cargo rustc --bin static-web-server --verbose --release --target="$BINARY_ARCH-unknown-freebsd"
    cargo build --bin static-web-server -vv --release --target="$BINARY_ARCH-unknown-freebsd" $CARGO_FEATURES
  archive_script: |
    staging="static-web-server-$CIRRUS_TAG-$BINARY_ARCH-unknown-freebsd"
    mkdir -p "$staging/"
diff --git a/.github/workflows/devel.yml b/.github/workflows/devel.yml
index 816a973..989d67b 100644
--- a/.github/workflows/devel.yml
+++ b/.github/workflows/devel.yml
@@ -38,6 +38,8 @@ jobs:
      RUST_BACKTRACE: 1
      # Skip tests
      SKIP_TESTS: ""
      # SWS features for Cargo build
      CARGO_FEATURES: "--features=all"
    strategy:
      matrix:
        build:
@@ -236,12 +238,12 @@ jobs:
    - name: Run tests
      shell: bash
      run: |
        ${{ env.CARGO_BIN }} test --verbose ${{ env.TARGET_FLAGS }} ${{ env.SKIP_TESTS }}
        ${{ env.CARGO_BIN }} test --verbose ${{ env.CARGO_FEATURES }} ${{ env.TARGET_FLAGS }} ${{ env.SKIP_TESTS }}

    - name: Run build
      shell: bash
      run: |
        ${{ env.CARGO_BIN }} rustc --bin static-web-server --verbose ${{ env.TARGET_FLAGS }}
        ${{ env.CARGO_BIN }} build --bin static-web-server -vv ${{ env.CARGO_FEATURES }} ${{ env.TARGET_FLAGS }}

    - name: Run executable
      shell: bash
diff --git a/.github/workflows/release.build.manual.yml b/.github/workflows/release.build.manual.yml
index 92916f8..e7e7b4a 100644
--- a/.github/workflows/release.build.manual.yml
+++ b/.github/workflows/release.build.manual.yml
@@ -20,6 +20,10 @@ jobs:
      TARGET_DIR: ./target
      # Emit backtraces on panics.
      RUST_BACKTRACE: 1
      # Rustc flags needed by the `all` features
      RUSTFLAGS: "--cfg tokio_unstable"
      # SWS features for Cargo build
      CARGO_FEATURES: "--features=all"
    strategy:
      matrix:
        build:
@@ -154,7 +158,7 @@ jobs:
        echo "target dir is: ${{ env.TARGET_DIR }}"

    - name: Build release binary
      run: ${{ env.CARGO_BIN }} rustc --bin static-web-server --verbose --release ${{ env.TARGET_FLAGS }}
      run: ${{ env.CARGO_BIN }} build --bin static-web-server -vv --release ${{ env.CARGO_FEATURES }} ${{ env.TARGET_FLAGS }}

    - name: Prepare Docker envs
      shell: bash
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 583d22a..4ec61d8 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -46,6 +46,8 @@ jobs:
      TARGET_DIR: ./target
      # Emit backtraces on panics.
      RUST_BACKTRACE: 1
      # SWS features for Cargo build
      CARGO_FEATURES: "--features=all"
    strategy:
      matrix:
        build:
@@ -214,7 +216,7 @@ jobs:
        echo "target dir is: ${{ env.TARGET_DIR }}"

    - name: Build release binary
      run: ${{ env.CARGO_BIN }} rustc --bin static-web-server --verbose --release ${{ env.TARGET_FLAGS }}
      run: ${{ env.CARGO_BIN }} build --bin static-web-server -vv --release ${{ env.CARGO_FEATURES }} ${{ env.TARGET_FLAGS }}

    - name: Build archive
      shell: bash
diff --git a/Cargo.toml b/Cargo.toml
index 312df1c..ee4e6fb 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -37,6 +37,7 @@ doc = false
[features]
# All features enabled by default
default = ["compression", "http2", "directory-listing", "basic-auth", "fallback-page"]
all = ["default", "experimental"]
# HTTP2
http2 = ["tokio-rustls", "rustls-pemfile"]
# Compression
@@ -51,6 +52,9 @@ directory-listing = ["humansize", "chrono"]
basic-auth = ["bcrypt"]
# Fallback Page
fallback-page = []
# Experimental features
# --experimental-metrics
experimental = ["tokio-metrics-collector", "prometheus"]

[dependencies]
aho-corasick = "1.1"
@@ -91,8 +95,8 @@ version = "0.5"
[target.'cfg(unix)'.dependencies]
signal-hook = { version = "0.3", features = ["extended-siginfo"] }
signal-hook-tokio = { version = "0.3", features = ["futures-v0_3"], default-features = false }
tokio-metrics-collector = "0.2"
prometheus = "0.13"
tokio-metrics-collector = { version = "0.2", optional = true }
prometheus = { version = "0.13", optional = true }

[target.'cfg(windows)'.dependencies]
windows-service = "0.6"
diff --git a/docs/content/building-from-source.md b/docs/content/building-from-source.md
index e6a9016..25fd058 100644
--- a/docs/content/building-from-source.md
+++ b/docs/content/building-from-source.md
@@ -29,7 +29,9 @@ However, you can disable just the ones you don't need from the lists below.
Feature | Description
---------|------
**Default** |
`default` | Activates all features by default.
`default` | Activates the default features by omission.
`all` | Activates all available features including the `experimental` feature. This is the default feature used when building SWS binaries.
`experimental` | Activates all SWS experimental features. Make sure to also provide the required `RUSTFLAGS` if the feature requires so.
[**HTTP2/TLS**]./features/http2-tls.md |
`http2` | Activates the HTTP2 and TLS feature.
[**Compression**]./features/compression.md |
@@ -52,8 +54,13 @@ For example, if you want to run or build SWS without the default features like `
```sh
# run
cargo run --no-default-features -- -h

# or build
cargo build --release --no-default-features

# or including all features (example)
RUSTFLAGS="--cfg tokio_unstable" \
    cargo build -vv --release --features all 
```

## Cross-compiling
@@ -75,6 +82,17 @@ Let's say, you want to cross-compile SWS from macOS to Linux. Then follow these 

Built binaries can be found under the corresponding toolchain directory inside `target/`.

## Testing

```sh
# run tests for default features
cargo test
# or run tests for all features including experimental ones
RUSTFLAGS="--cfg tokio_unstable" cargo test --features all
# or run specific tests
cargo test --test rewrites
```

## Building documentation from source

All HTML documentation is located in the `docs/` project's directory and is built using [Material for MkDocs]https://github.com/squidfunk/mkdocs-material.
diff --git a/src/handler.rs b/src/handler.rs
index 48cd289..0106516 100644
--- a/src/handler.rs
+++ b/src/handler.rs
@@ -81,7 +81,7 @@ pub struct RequestHandlerOpts {
    /// Health endpoint feature.
    pub health: bool,
    /// Metrics endpoint feature (experimental).
    #[cfg(unix)]
    #[cfg(all(unix, feature = "experimental"))]
    pub experimental_metrics: bool,
    /// Maintenance mode feature.
    pub maintenance_mode: bool,
@@ -125,7 +125,7 @@ impl RequestHandler {
        let compression_static = self.opts.compression_static;
        let ignore_hidden_files = self.opts.ignore_hidden_files;
        let health = self.opts.health;
        #[cfg(unix)]
        #[cfg(all(unix, feature = "experimental"))]
        let experimental_metrics = self.opts.experimental_metrics;
        let index_files: Vec<&str> = self.opts.index_files.iter().map(|s| s.as_str()).collect();

@@ -134,7 +134,7 @@ impl RequestHandler {
        let health_request =
            health && uri_path == "/health" && (method.is_get() || method.is_head());

        #[cfg(unix)]
        #[cfg(all(unix, feature = "experimental"))]
        let metrics_request =
            experimental_metrics && uri_path == "/metrics" && (method.is_get() || method.is_head());

@@ -202,7 +202,7 @@ impl RequestHandler {
            }

            // Metrics endpoint check
            #[cfg(unix)]
            #[cfg(all(unix, feature = "experimental"))]
            if metrics_request {
                use prometheus::Encoder;

diff --git a/src/server.rs b/src/server.rs
index 3e3613c..333c8c9 100644
--- a/src/server.rs
+++ b/src/server.rs
@@ -293,15 +293,15 @@ impl Server {
        server_info!("health endpoint: enabled={}", health);

        // Metrics endpoint option (experimental)
        #[cfg(unix)]
        #[cfg(all(unix, feature = "experimental"))]
        let experimental_metrics = general.experimental_metrics;
        #[cfg(unix)]
        #[cfg(all(unix, feature = "experimental"))]
        server_info!(
            "metrics endpoint (experimental): enabled={}",
            experimental_metrics
        );

        #[cfg(unix)]
        #[cfg(all(unix, feature = "experimental"))]
        if experimental_metrics {
            prometheus::default_registry()
                .register(Box::new(
@@ -350,7 +350,7 @@ impl Server {
                ignore_hidden_files,
                index_files,
                health,
                #[cfg(unix)]
                #[cfg(all(unix, feature = "experimental"))]
                experimental_metrics,
                maintenance_mode,
                maintenance_mode_status,
diff --git a/src/settings/cli.rs b/src/settings/cli.rs
index 3f24843..60f912e 100644
--- a/src/settings/cli.rs
+++ b/src/settings/cli.rs
@@ -400,7 +400,7 @@ pub struct General {
    /// This is especially useful with Kubernetes liveness and readiness probes.
    pub health: bool,

    #[cfg(unix)]
    #[cfg(all(unix, feature = "experimental"))]
    #[arg(
        long = "experimental-metrics",
        default_value = "false",
diff --git a/src/settings/file.rs b/src/settings/file.rs
index 05ae5a7..19e3bf0 100644
--- a/src/settings/file.rs
+++ b/src/settings/file.rs
@@ -239,7 +239,7 @@ pub struct General {
    /// Health endpoint feature.
    pub health: Option<bool>,

    #[cfg(unix)]
    #[cfg(all(unix, feature = "experimental"))]
    /// Metrics endpoint feature (experimental).
    pub experimental_metrics: Option<bool>,

diff --git a/src/settings/mod.rs b/src/settings/mod.rs
index b641676..2114c91 100644
--- a/src/settings/mod.rs
+++ b/src/settings/mod.rs
@@ -149,7 +149,8 @@ impl Settings {
        let mut ignore_hidden_files = opts.ignore_hidden_files;
        let mut index_files = opts.index_files;
        let mut health = opts.health;
        #[cfg(unix)]

        #[cfg(all(unix, feature = "experimental"))]
        let mut experimental_metrics = opts.experimental_metrics;

        let mut maintenance_mode = opts.maintenance_mode;
@@ -296,7 +297,7 @@ impl Settings {
                if let Some(v) = general.health {
                    health = v
                }
                #[cfg(unix)]
                #[cfg(all(unix, feature = "experimental"))]
                if let Some(v) = general.experimental_metrics {
                    experimental_metrics = v
                }
@@ -553,7 +554,7 @@ impl Settings {
                ignore_hidden_files,
                index_files,
                health,
                #[cfg(unix)]
                #[cfg(all(unix, feature = "experimental"))]
                experimental_metrics,
                maintenance_mode,
                maintenance_mode_status,
diff --git a/src/testing.rs b/src/testing.rs
index 75a637e..ef27a7e 100644
--- a/src/testing.rs
+++ b/src/testing.rs
@@ -52,7 +52,7 @@ pub mod fixtures {
            ignore_hidden_files: opts.general.ignore_hidden_files,
            index_files: vec![opts.general.index_files],
            health: opts.general.health,
            #[cfg(unix)]
            #[cfg(all(unix, feature = "experimental"))]
            experimental_metrics: opts.general.experimental_metrics,
            maintenance_mode: opts.general.maintenance_mode,
            maintenance_mode_status: opts.general.maintenance_mode_status,
diff --git a/tests/experimental_metrics.rs b/tests/experimental_metrics.rs
index 597155d..fed395c 100644
--- a/tests/experimental_metrics.rs
+++ b/tests/experimental_metrics.rs
@@ -3,7 +3,7 @@
#![deny(rust_2018_idioms)]
#![deny(dead_code)]

#[cfg(unix)]
#[cfg(all(unix, feature = "experimental"))]
pub mod tests {
    use hyper::Request;
    use std::net::SocketAddr;