http env flag

AuthorKonata <konata@posteo.jp>
Date
Commitc268712034f0e7e8fd5ef1521c6f294fed977d39
Parent5e157b7
3 files changed, 25 insertions(+), 3 deletions(-)
▾MREADME.md
@@ -66,7 +66,7 @@ filebrowser-ng --root /srv/files --db /var/lib/filebrowser/db.sqlite --bind 0.0.
| `--db` | _(required)_ | SQLite file. Created when missing. |
| `--port` | `8080` | Listen port |
| `--bind` | `127.0.0.1` | Listen address. `0.0.0.0` exposes the server beyond localhost. |
| `--https` | off | Set when behind a TLS-terminating proxy. Marks the cookie `Secure`. |
| `--https` | off | Set when behind a TLS-terminating proxy. Marks the cookie `Secure`. Also `FILEBROWSER_HTTPS=true`. |
| `--root-name` | folder name | Display name of the root folder. Also `FILEBROWSER_ROOT_NAME`. |
Log level comes from `RUST_LOG` (`error`, `warn`, `info`, `debug`, `trace`).
@@ -74,7 +74,7 @@ Log level comes from `RUST_LOG` (`error`, `warn`, `info`, `debug`, `trace`).
### Reverse proxy
The server speaks plain HTTP. Put a TLS-terminating proxy in front of it and
pass `--https`. Without the flag the session cookie is sent over plain HTTP
pass `--https`, or set `FILEBROWSER_HTTPS=true` in `compose.yml`. Without the flag the session cookie is sent over plain HTTP
as well. Search uses server-sent events, so the proxy must not buffer
responses on `/api/search`.
▾Mcompose.yml
@@ -6,6 +6,7 @@ services:
- "8080:8080"
environment:
RUST_LOG: info # server log level: trace/debug/info/warn/error
# FILEBROWSER_HTTPS: "true" # behind a TLS-terminating proxy: marks the session cookie Secure
# FILEBROWSER_ROOT_NAME: Media # UI name of the root folder (default: its folder name, here "data")
volumes:
- ./data:/data # browsed files (server --root)
▾Mserver/src/cli.rs
@@ -33,7 +33,8 @@ pub struct Cli {
/// Assume the server runs behind a TLS-terminating reverse proxy
/// (sets the `Secure` attribute on the session cookie).
#[arg(long)]
/// The env form takes `true` or `false`.
#[arg(long, env = "FILEBROWSER_HTTPS")]
pub https: bool,
}
@@ -43,8 +44,12 @@ mod tests {
use clap::Parser;
use std::path::PathBuf;
/// `defaults_applied` asserts `!https`, which the env var would flip.
static ENV_LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(());
#[test]
fn defaults_applied() {
let _guard = ENV_LOCK.lock().unwrap();
let c = Cli::try_parse_from(["filebrowser-ng", "--root", "/r", "--db", "/d"]).unwrap();
assert_eq!(c.root, PathBuf::from("/r"));
assert_eq!(c.db, PathBuf::from("/d"));
@@ -73,6 +78,22 @@ mod tests {
assert!(c.https);
}
#[test]
fn https_from_env() {
// Env-driven flags carry the daemon's whole config: the compose file
// has no `command:` and must still be able to turn this on.
let _guard = ENV_LOCK.lock().unwrap();
// clap accepts only these two literals for a flag read from the env.
for (val, want) in [("true", true), ("false", false)] {
// SAFETY: the process env is shared; ENV_LOCK serialises every test
// that reads or writes it.
unsafe { std::env::set_var("FILEBROWSER_HTTPS", val) };
let c = Cli::try_parse_from(["filebrowser-ng", "--root", "/r", "--db", "/d"]).unwrap();
assert_eq!(c.https, want, "FILEBROWSER_HTTPS={val}");
}
unsafe { std::env::remove_var("FILEBROWSER_HTTPS") };
}
#[test]
fn required_args_enforced() {
assert!(Cli::try_parse_from(["filebrowser-ng", "--root", "/r"]).is_err());