agate

Simple gemini server for static files
git clone https://github.com/mbrubeck/agate.git
Log | Files | Refs | README

commit b0d0f64be094ecdda8c49ea7846d09921474923e
parent ba3c01d38f85c11326f365a6f6be780e698afca4
Author: Johann150 <johann.galle@protonmail.com>
Date:   Sun, 18 Jul 2021 11:30:17 +0200

actually bind to multiple addresses

resolves #63

This now causes an error message with the default bindings because on Linux
binding to both IPv6's [::] and IPv4's 0.0.0.0 results in a "port in use" error

Diffstat:
MCHANGELOG.md | 6+++++-
MCargo.lock | 122++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------
MCargo.toml | 1+
Msrc/main.rs | 62++++++++++++++++++++++++++++++++++++++------------------------
Mtests/tests.rs | 2+-
5 files changed, 141 insertions(+), 52 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md @@ -6,11 +6,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] -Thank you to @jgarte for contributing to this release. +Thank you to @jgarte and @alvaro-cuesta for contributing to this release. ### Added * running Agate using GNU Guix (#62) +### Fixed +* actually bind to multiple IP addresses. Despite the documentation saying so, + Agate would only bind to the first address that did not result in an error. (#63) + ## [3.1.0] - 2021-06-08 Thank you to Matthew Ingwersen and Oliver Simmons (@GoodClover) for contributing to this release. diff --git a/Cargo.lock b/Cargo.lock @@ -1,5 +1,7 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "agate" version = "3.1.0" @@ -7,6 +9,7 @@ dependencies = [ "anyhow", "configparser", "env_logger", + "futures-util", "gemini-fetch", "getopts", "glob", @@ -24,9 +27,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.40" +version = "1.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b2cd92db5cbd74e8e5028f7e27dd7aa3090e89e4f2a197cc7c8dfb69c7063b" +checksum = "595d3cfa7a60d4555cb5067b99f07142a08ea778de5cf993f7b75c7d8fabc486" [[package]] name = "atty" @@ -65,9 +68,9 @@ checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040" [[package]] name = "cc" -version = "1.0.68" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a72c244c1ff497a746a7e1fb3d14bd08420ecda70c8f25c7112f2781652d787" +checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2" [[package]] name = "cfg-if" @@ -93,9 +96,9 @@ checksum = "f7201ee416d124d589a820111ba755930df8b75855321a9a1b87312a0597ec8f" [[package]] name = "env_logger" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17392a012ea30ef05a610aa97dfb49496e71c9f676b27879922ea5bdf60d9d3f" +checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3" dependencies = [ "atty", "humantime", @@ -114,6 +117,48 @@ dependencies = [ ] [[package]] +name = "futures-core" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0402f765d8a89a26043b889b26ce3c4679d268fa6bb22cd7c6aad98340e179d1" + +[[package]] +name = "futures-macro" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c40298486cdf52cc00cd6d6987892ba502c7656a16a4192a9992b1ccedd121" +dependencies = [ + "autocfg", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-task" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a16bef9fc1a4dddb5bee51c989e3fbba26569cbb0e31f5b303c184e3dd33dae" + +[[package]] +name = "futures-util" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "feb5c238d27e2bf94ffdfd27b2c29e3df4a68c4193bb6427384259e2bf191967" +dependencies = [ + "autocfg", + "futures-core", + "futures-macro", + "futures-task", + "pin-project-lite", + "pin-utils", + "proc-macro-hack", + "proc-macro-nested", + "slab", +] + +[[package]] name = "gemini-fetch" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -148,9 +193,9 @@ checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" [[package]] name = "hermit-abi" -version = "0.1.18" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" dependencies = [ "libc", ] @@ -189,9 +234,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.95" +version = "0.2.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "789da6d93f1b866ffe175afc5322a4d76c038605a1c3319bb57b06967ca98a36" +checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790" [[package]] name = "log" @@ -232,9 +277,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.7.11" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf80d3e903b34e0bd7282b218398aec54e082c840d9baf8339e0080a0c542956" +checksum = "8c2bdb6314ec10835cd3293dd268473a835c02b7b352e788be788b3c6ca6bb16" dependencies = [ "libc", "log", @@ -292,9 +337,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.7.2" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3" +checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" [[package]] name = "pem" @@ -315,9 +360,27 @@ checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" [[package]] name = "pin-project-lite" -version = "0.2.6" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "proc-macro-hack" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" + +[[package]] +name = "proc-macro-nested" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc0e1f259c92177c30a4c9d177246edd0a3568b25756a977d0632cf8fa37e905" +checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" [[package]] name = "proc-macro2" @@ -403,6 +466,12 @@ dependencies = [ ] [[package]] +name = "slab" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f173ac3d1a7e3b28003f40de0b5ce7fe2710f9b9dc3fc38664cebee46b3b6527" + +[[package]] name = "spin" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -410,9 +479,9 @@ checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" [[package]] name = "syn" -version = "1.0.72" +version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1e8cdbefb79a9a5a65e0db8b47b723ee907b7c7f8496c76a1770b5c310bab82" +checksum = "f71489ff30030d2ae598524f61326b902466f72a0fb1a8564c001cc63425bcc7" dependencies = [ "proc-macro2", "quote", @@ -430,18 +499,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.25" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa6f76457f59514c7eeb4e59d891395fab0b2fd1d40723ae737d64153392e9c6" +checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.25" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a36768c0fbf1bb15eca10defa29526bda730a2376c2ab4393ccfa16fb1a318d" +checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745" dependencies = [ "proc-macro2", "quote", @@ -465,9 +534,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.6.1" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a38d31d7831c6ed7aad00aa4c12d9375fd225a6dd77da1d25b707346319a975" +checksum = "98c8b05dc14c75ea83d63dd391100353789f5f24b8b3866542a5e85c8be8e985" dependencies = [ "autocfg", "bytes", @@ -477,13 +546,14 @@ dependencies = [ "num_cpus", "pin-project-lite", "tokio-macros", + "winapi", ] [[package]] name = "tokio-macros" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c49e3df43841dafb86046472506755d8501c5615673955f6aa17181125d13c37" +checksum = "54473be61f4ebe4efd09cec9bd5d16fa51d70ea0192213d754d2d500457db110" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml @@ -14,6 +14,7 @@ exclude = ["/tools", "/.github", "/release.sh", "/Cross.toml", "/content", "/COD [dependencies] configparser = "2.0" env_logger = { version = "0.8", default-features = false, features = ["atty", "humantime", "termcolor"] } +futures-util = "0.3" getopts = "0.2.21" glob = "0.3" log = "0.4" diff --git a/src/main.rs b/src/main.rs @@ -30,37 +30,51 @@ use { url::{Host, Url}, }; -fn main() -> Result { +fn main() { env_logger::Builder::from_env( // by default only turn on logging for agate env_logger::Env::default().default_filter_or("agate=info"), ) .init(); - Runtime::new()?.block_on(async { - let default = PresetMeta::Parameters( - ARGS.language - .as_ref() - .map_or(String::new(), |lang| format!(";lang={}", lang)), - ); - let mimetypes = Arc::new(Mutex::new(FileOptions::new(default))); - let listener = TcpListener::bind(&ARGS.addrs[..]).await?; - log::info!("Listening on {:?}...", ARGS.addrs); - loop { - let (stream, _) = listener.accept().await?; - let arc = mimetypes.clone(); - tokio::spawn(async { - match RequestHandle::new(stream, arc).await { - Ok(handle) => match handle.handle().await { - Ok(info) => log::info!("{}", info), - Err(err) => log::warn!("{}", err), - }, - Err(log_line) => { - log::warn!("{}", log_line); + Runtime::new() + .expect("could not start tokio runtime") + .block_on(async { + let default = PresetMeta::Parameters( + ARGS.language + .as_ref() + .map_or(String::new(), |lang| format!(";lang={}", lang)), + ); + let mimetypes = Arc::new(Mutex::new(FileOptions::new(default))); + + let handles = ARGS.addrs.iter().map(|addr| { + let arc = mimetypes.clone(); + tokio::spawn(async move { + let listener = TcpListener::bind(addr) + .await + .unwrap_or_else(|e| panic!("Failed to listen on {}: {}", addr, e)); + log::info!("Started listener on {}", addr); + loop { + let (stream, _) = listener.accept().await.unwrap_or_else(|e| { + panic!("could not accept new connection on {}: {}", addr, e) + }); + let arc = arc.clone(); + tokio::spawn(async { + match RequestHandle::new(stream, arc).await { + Ok(handle) => match handle.handle().await { + Ok(info) => log::info!("{}", info), + Err(err) => log::warn!("{}", err), + }, + Err(log_line) => { + log::warn!("{}", log_line); + } + } + }); } - } + }) }); - } - }) + + futures_util::future::join_all(handles).await; + }); } type Result<T = (), E = Box<dyn Error + Send + Sync>> = std::result::Result<T, E>; diff --git a/tests/tests.rs b/tests/tests.rs @@ -40,7 +40,7 @@ impl Server { let mut buffer = String::new(); while matches!(reader.read_line(&mut buffer), Ok(i) if i>0) { print!("log: {}", buffer); - if buffer.contains("Listening") { + if buffer.contains("Started") { break; }