Repository: static-web-server/static-web-server (language: rust)

Issue:
2.18 regression: errors out with empty SERVER_FALLBACK_PAGE
**Describe the bug**
With the following Dockerfile, I could run the resulting image even with an empty `SERVER_FALLBACK_PAGE`:
```Dockerfile
ARG STATIC_WEB_SERVER_VERSION=2.17
FROM joseluisq/static-web-server:${STATIC_WEB_SERVER_VERSION}

# SWS configuration, check https://sws.joseluisq.net/configuration/environment-variables/
ENV SERVER_ROOT=/public

# Set fallback page for Single-page Applications
ARG SERVER_FALLBACK_PAGE
ENV SERVER_FALLBACK_PAGE=${SERVER_FALLBACK_PAGE}

# The whole website
COPY public/ /public/
```

Now, setting STATIC_WEB_SERVER_VERSION to 2.18, the same build gives:
```bash
error: a value is required for '--page-fallback <PAGE_FALLBACK>' but none was supplied
```
**To Reproduce**
Set an empty `SERVER_FALLBACK_PAGE` environment variable:

```bash
# Works
$ docker run -e SERVER_FALLBACK_PAGE= joseluisq/static-web-server:2.17
^C
# Fails
$ docker run -e SERVER_FALLBACK_PAGE= joseluisq/static-web-server:2.18
error: a value is required for '--page-fallback <PAGE_FALLBACK>' but none was supplied

For more information, try '--help'.
```

**Environment and Specs**
 - static-web-server: 2.18

This seems to be a regression caused by https://github.com/static-web-server/static-web-server/pull/215


Discussion / hints:
Thanks for that!
We will fix that definitely, in fact, will be trivial to be fixed.
But for now, the "workaround" should be to unset the `SERVER_FALLBACK_PAGE` and avoid passing it to SWS if empty.
In fact, I've found that I can pass `false` to it too;

```Dockerfile
ARG STATIC_WEB_SERVER_VERSION=2.18
FROM joseluisq/static-web-server:${STATIC_WEB_SERVER_VERSION}

# SWS configuration, check https://sws.joseluisq.net/configuration/environment-variables/
ENV SERVER_ROOT=/public

# Set fallback page for Single-page Applications
ARG SERVER_FALLBACK_PAGE=false
ENV SERVER_FALLBACK_PAGE=${SERVER_FALLBACK_PAGE}

# The whole website
COPY public/ /public/
```

This is thanks to https://docs.rs/clap/latest/clap/struct.Arg.html#method.env:

> Note that the value parser controls how flags are parsed. In this case we’ve selected [FalseyValueParser](https://docs.rs/clap/latest/clap/builder/struct.FalseyValueParser.html). A false literal is n, no, f, false, off or 0. An absent environment variable will also be considered as false. Anything else will considered as true.

Fix patch:
diff --git a/src/server.rs b/src/server.rs
index 0fbbfe16..cdd3b813 100644
--- a/src/server.rs
+++ b/src/server.rs
@@ -154,7 +154,18 @@ impl Server {
         let page50x = helpers::read_bytes_default(&general.page50x);
 
         // Fallback page content
-        let page_fallback = helpers::read_bytes_default(&general.page_fallback.unwrap_or_default());
+        let page_fallback_pbuf = general.page_fallback;
+        let page_fallback = helpers::read_bytes_default(&page_fallback_pbuf);
+        let page_fallback_enabled = !page_fallback.is_empty();
+        let mut page_fallback_opt = "";
+        if page_fallback_enabled {
+            page_fallback_opt = page_fallback_pbuf.to_str().unwrap()
+        }
+        tracing::info!(
+            "fallback page: enabled={}, value=\"{}\"",
+            page_fallback_enabled,
+            page_fallback_opt
+        );
 
         // Number of worker threads option
         let threads = self.worker_threads;
diff --git a/src/settings/cli.rs b/src/settings/cli.rs
index b1cceddf..75a4214b 100644
--- a/src/settings/cli.rs
+++ b/src/settings/cli.rs
@@ -8,7 +8,7 @@
 use clap::Parser;
 use std::path::PathBuf;
 
-use crate::directory_listing::DirListFmt;
+use crate::{directory_listing::DirListFmt, Result};
 
 /// General server configuration available in CLI and config file options.
 #[derive(Parser, Debug)]
@@ -102,9 +102,9 @@ pub struct General {
     /// HTML file path for 404 errors. If the path is not specified or simply doesn't exist then the server will use a generic HTML error message.
     pub page404: PathBuf,
 
-    #[arg(long, env = "SERVER_FALLBACK_PAGE")]
+    #[arg(long, default_value = "", value_parser = value_parser_pathbuf, env = "SERVER_FALLBACK_PAGE")]
     /// 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>,
+    pub page_fallback: PathBuf,
 
     #[arg(long, short = 'g', default_value = "error", env = "SERVER_LOG_LEVEL")]
     /// Specify a logging level in lower case. Values: error, warn, info, debug or trace
@@ -392,3 +392,7 @@ pub enum Commands {
     #[command(name = "uninstall")]
     Uninstall {},
 }
+
+fn value_parser_pathbuf(s: &str) -> Result<PathBuf, String> {
+    Ok(PathBuf::from(s))
+}
diff --git a/src/settings/mod.rs b/src/settings/mod.rs
index 9edf3421..0a1f1ba7 100644
--- a/src/settings/mod.rs
+++ b/src/settings/mod.rs
@@ -239,7 +239,7 @@ impl Settings {
                         grace_period = v
                     }
                     if let Some(v) = general.page_fallback {
-                        page_fallback = Some(v)
+                        page_fallback = v
                     }
                     if let Some(v) = general.log_remote_address {
                         log_remote_address = v


Test patch: