commit bd9ed3255a8c43d51a6d71edc912d17319f43443
parent 8fd9ca15c3df8757b0268f9be49a952142fb333f
Author: Johann150 <johann.galle@protonmail.com>
Date: Thu, 11 Feb 2021 08:57:59 +0100
add central configuration mode
also slight correction of the documentation because we are now using YAML
(a space is now required behind the colon)
Diffstat:
4 files changed, 36 insertions(+), 12 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
@@ -13,8 +13,10 @@ Thank you to @gegeweb for contributing to this release.
* You can now supply multiple `--hostname`s to enable basic vhosts (#28).
* Disabling support for TLSv1.2 can now be done using the `--only-tls13` flag, but this is *NOT RECOMMENDED* (#12).
* The tools now also contain a startup script for FreeBSD (#13).
+* Using central config mode (flag `-C`), all configuration can be done in one `.meta` file (see README.md for details).
### Changed
+* The configuration files are now parsed as YAML. The syntax only changes in that a space is now required behind the colon.
* The changelog is now also kept in this file in addition to the GitHub releases.
* Certificate chain and key file are now only loaded once at startup, certificate changes need a restart to take effect.
diff --git a/README.md b/README.md
@@ -67,7 +67,7 @@ A file called `index.gmi` will always take precedence over a directory listing.
You can put a file called `.meta` in a directory. This file stores some metadata about these files which Agate will use when serving these files. The file should be UTF-8 encoded. Like the `.directory-listing-ok` file, this file does not have an effect on sub-directories. (*1)
This file is parsed as a YAML file and should contain a "hash" datatype with file names as the keys. This means:
-Lines starting with a `#` are comments and will be ignored like empty lines. All other lines must start with a file name, followed by a colon and then the metadata.
+Lines starting with a `#` are comments and will be ignored like empty lines. All other lines must start with a file name, followed by a colon and a space and then the metadata.
The metadata can take one of four possible forms:
1. empty
@@ -85,11 +85,13 @@ If a line violates the format or looks like case 3, but is incorrect, it might b
Such a configuration file might look like this:
```text
# This line will be ignored.
-index.gmi:;lang=en-UK
-LICENSE:text/plain;charset=UTF-8
-gone.gmi:52 This file is no longer here, sorry.
+index.gmi: ;lang=en-UK
+LICENSE: text/plain;charset=UTF-8
+gone.gmi: 52 This file is no longer here, sorry.
```
+You can enable a central configuration file with the `-C` flag (or the long version `--central-conf`). In this case Agate will always look for the `.meta` configuration file in the content root directory and will ignore `.meta` files in other directories.
+
(*1) It is *theoretically* possible to specify information on files which are in sub-directories. The problem would only be to make sure that this file is loaded before the respective path/file is requested. This is because Agate does not actively check that the "no sub-directories" regulation is met. In fact this might be dropped in a change of configuration format in the foreseeable future.
### Logging Verbosity
diff --git a/src/main.rs b/src/main.rs
@@ -9,8 +9,15 @@ use {
Certificate, NoClientAuth, PrivateKey, ServerConfig,
},
std::{
- borrow::Cow, error::Error, ffi::OsStr, fmt::Write, fs::File, io::BufReader,
- net::SocketAddr, path::Path, sync::Arc,
+ borrow::Cow,
+ error::Error,
+ ffi::OsStr,
+ fmt::Write,
+ fs::File,
+ io::BufReader,
+ net::SocketAddr,
+ path::{Path, PathBuf},
+ sync::Arc,
},
tokio::{
io::{AsyncReadExt, AsyncWriteExt},
@@ -67,7 +74,7 @@ static ARGS: Lazy<Args> = Lazy::new(|| {
struct Args {
addrs: Vec<SocketAddr>,
- content_dir: String,
+ content_dir: PathBuf,
cert_chain: Vec<Certificate>,
key: PrivateKey,
hostnames: Vec<Host>,
@@ -76,6 +83,7 @@ struct Args {
serve_secret: bool,
log_ips: bool,
only_tls13: bool,
+ central_config: bool,
}
fn args() -> Result<Args> {
@@ -130,6 +138,11 @@ fn args() -> Result<Args> {
"Enable serving secret files (files/directories starting with a dot)",
);
opts.optflag("", "log-ip", "Output IP addresses when logging");
+ opts.optflag(
+ "C",
+ "central-conf",
+ "Use a central .meta file in the content root directory.",
+ );
let matches = opts.parse(&args[1..]).map_err(|f| f.to_string())?;
if matches.opt_present("h") {
@@ -176,14 +189,16 @@ fn args() -> Result<Args> {
serve_secret: matches.opt_present("serve-secret"),
log_ips: matches.opt_present("log-ip"),
only_tls13: matches.opt_present("only-tls13"),
+ central_config: matches.opt_present("central-conf"),
})
}
-fn check_path(s: String) -> Result<String, String> {
- if Path::new(&s).exists() {
- Ok(s)
+fn check_path(s: String) -> Result<PathBuf, String> {
+ let p = PathBuf::from(s);
+ if p.as_path().exists() {
+ Ok(p)
} else {
- Err(format!("No such file: {}", s))
+ Err(format!("No such file: {:?}", p))
}
}
diff --git a/src/metadata.rs b/src/metadata.rs
@@ -193,7 +193,12 @@ impl FileOptions {
/// working/content directory. If inconsisten file paths are used, this can
/// lead to loading and storing sidecar files multiple times.
pub fn get(&mut self, file: &PathBuf) -> PresetMeta {
- let dir = file.parent().expect("no parent directory").to_path_buf();
+ let dir = if super::ARGS.central_config {
+ super::ARGS.content_dir.clone()
+ } else {
+ file.parent().expect("no parent directory").to_path_buf()
+ };
+
if self.check_outdated(&dir) {
self.read_database(&dir);
}