agate

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

commit 471a9927a06d09f70f3eba42030908c96a95beac
parent beb05662012149afad66129e1b9b0911294994d9
Author: Matt Brubeck <mbrubeck@limpet.net>
Date:   Thu, 31 Dec 2020 18:00:03 -0800

Use the Tokio async runtime

Diffstat:
MCargo.lock | 367++++++++++++++-----------------------------------------------------------------
MCargo.toml | 4++--
Msrc/main.rs | 29+++++++++++++----------------
3 files changed, 79 insertions(+), 321 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock @@ -4,8 +4,6 @@ name = "agate" version = "2.1.2" dependencies = [ - "async-std", - "async-tls", "env_logger", "getopts", "log", @@ -13,128 +11,12 @@ dependencies = [ "once_cell", "percent-encoding", "rustls", + "tokio", + "tokio-rustls", "url", ] [[package]] -name = "async-channel" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59740d83946db6a5af71ae25ddf9562c2b176b2ca42cf99a455f09f4a220d6b9" -dependencies = [ - "concurrent-queue", - "event-listener", - "futures-core", -] - -[[package]] -name = "async-executor" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb877970c7b440ead138f6321a3b5395d6061183af779340b65e20c0fede9146" -dependencies = [ - "async-task", - "concurrent-queue", - "fastrand", - "futures-lite", - "once_cell", - "vec-arena", -] - -[[package]] -name = "async-global-executor" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73079b49cd26b8fd5a15f68fc7707fc78698dc2a3d61430f2a7a9430230dfa04" -dependencies = [ - "async-executor", - "async-io", - "futures-lite", - "num_cpus", - "once_cell", -] - -[[package]] -name = "async-io" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9315f8f07556761c3e48fec2e6b276004acf426e6dc068b2c2251854d65ee0fd" -dependencies = [ - "concurrent-queue", - "fastrand", - "futures-lite", - "libc", - "log", - "nb-connect", - "once_cell", - "parking", - "polling", - "vec-arena", - "waker-fn", - "winapi", -] - -[[package]] -name = "async-mutex" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479db852db25d9dbf6204e6cb6253698f175c15726470f78af0d918e99d6156e" -dependencies = [ - "event-listener", -] - -[[package]] -name = "async-std" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f9f84f1280a2b436a2c77c2582602732b6c2f4321d5494d6e799e6c367859a8" -dependencies = [ - "async-channel", - "async-global-executor", - "async-io", - "async-mutex", - "blocking", - "crossbeam-utils", - "futures-channel", - "futures-core", - "futures-io", - "futures-lite", - "gloo-timers", - "kv-log-macro", - "log", - "memchr", - "num_cpus", - "once_cell", - "pin-project-lite", - "pin-utils", - "slab", - "wasm-bindgen-futures", -] - -[[package]] -name = "async-task" -version = "4.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91831deabf0d6d7ec49552e489aed63b7456a7a3c46cff62adad428110b0af0" - -[[package]] -name = "async-tls" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f23d769dbf1838d5df5156e7b1ad404f4c463d1ac2c6aeb6cd943630f8a8400" -dependencies = [ - "futures-core", - "futures-io", - "rustls", -] - -[[package]] -name = "atomic-waker" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "065374052e7df7ee4047b1160cca5e1467a12351a40b3da123c870ba0b8eda2a" - -[[package]] name = "atty" version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -158,30 +40,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" [[package]] -name = "blocking" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5e170dbede1f740736619b776d7251cb1b9095c435c34d8ca9f57fcd2f335e9" -dependencies = [ - "async-channel", - "async-task", - "atomic-waker", - "fastrand", - "futures-lite", - "once_cell", -] - -[[package]] name = "bumpalo" version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820" [[package]] -name = "cache-padded" -version = "1.1.1" +name = "bytes" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "631ae5198c9be5e753e5cc215e1bd73c2b466a3565173db433f52bb9d3e66dba" +checksum = "ad1f8e949d755f9d79112b5bb46938e0ef9d3804a0b16dfab13aafcaa5f0fa72" [[package]] name = "cc" @@ -202,26 +70,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] -name = "concurrent-queue" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30ed07550be01594c6026cff2a1d7fe9c8f683caa798e12b68694ac9e88286a3" -dependencies = [ - "cache-padded", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d" -dependencies = [ - "autocfg", - "cfg-if 1.0.0", - "lazy_static", -] - -[[package]] name = "env_logger" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -234,21 +82,6 @@ dependencies = [ ] [[package]] -name = "event-listener" -version = "2.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7531096570974c3a9dcf9e4b8e1cede1ec26cf5046219fb3b9d897503b9be59" - -[[package]] -name = "fastrand" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca5faf057445ce5c9d4329e382b2ce7ca38550ef3b73a5348362d5f24e0c7fe3" -dependencies = [ - "instant", -] - -[[package]] name = "form_urlencoded" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -259,42 +92,6 @@ dependencies = [ ] [[package]] -name = "futures-channel" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b7109687aa4e177ef6fe84553af6280ef2778bdb7783ba44c9dc3399110fe64" -dependencies = [ - "futures-core", -] - -[[package]] -name = "futures-core" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "847ce131b72ffb13b6109a221da9ad97a64cbe48feb1028356b836b47b8f1748" - -[[package]] -name = "futures-io" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "611834ce18aaa1bd13c4b374f5d653e1027cf99b6b502584ff8c9a64413b30bb" - -[[package]] -name = "futures-lite" -version = "1.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4481d0cd0de1d204a4fa55e7d45f07b1d958abcb06714b3446438e2eff695fb" -dependencies = [ - "fastrand", - "futures-core", - "futures-io", - "memchr", - "parking", - "pin-project-lite", - "waker-fn", -] - -[[package]] name = "getopts" version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -304,19 +101,6 @@ dependencies = [ ] [[package]] -name = "gloo-timers" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47204a46aaff920a1ea58b11d03dec6f704287d27561724a4631e450654a891f" -dependencies = [ - "futures-channel", - "futures-core", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] name = "hermit-abi" version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -343,15 +127,6 @@ dependencies = [ ] [[package]] -name = "instant" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec" -dependencies = [ - "cfg-if 1.0.0", -] - -[[package]] name = "js-sys" version = "0.3.46" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -361,15 +136,6 @@ dependencies = [ ] [[package]] -name = "kv-log-macro" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" -dependencies = [ - "log", -] - -[[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -419,12 +185,34 @@ dependencies = [ ] [[package]] -name = "nb-connect" -version = "1.0.2" +name = "mio" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8123a81538e457d44b933a02faf885d3fe8408806b23fa700e8f01c6c3a98998" +checksum = "e50ae3f04d169fcc9bde0b547d1c205219b7157e07ded9c5aff03e0637cb3ed7" dependencies = [ "libc", + "log", + "miow", + "ntapi", + "winapi", +] + +[[package]] +name = "miow" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a33c1b55807fbed163481b5ba66db4b2fa6cde694a5027be10fb724206c5897" +dependencies = [ + "socket2", + "winapi", +] + +[[package]] +name = "ntapi" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" +dependencies = [ "winapi", ] @@ -445,12 +233,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0" [[package]] -name = "parking" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" - -[[package]] name = "percent-encoding" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -463,25 +245,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b063f57ec186e6140e2b8b6921e5f1bd89c7356dda5b33acc5401203ca6131c" [[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "polling" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2a7bc6b2a29e632e45451c941832803a18cce6781db04de8a04696cdca8bde4" -dependencies = [ - "cfg-if 0.1.10", - "libc", - "log", - "wepoll-sys", - "winapi", -] - -[[package]] name = "proc-macro2" version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -538,10 +301,15 @@ dependencies = [ ] [[package]] -name = "slab" -version = "0.4.2" +name = "socket2" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" +checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "winapi", +] [[package]] name = "spin" @@ -585,6 +353,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] +name = "tokio" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d258221f566b6c803c7b4714abadc080172b272090cdc5e244a6d4dd13c3a6bd" +dependencies = [ + "autocfg", + "bytes", + "libc", + "memchr", + "mio", + "num_cpus", + "pin-project-lite", +] + +[[package]] +name = "tokio-rustls" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6" +dependencies = [ + "rustls", + "tokio", + "webpki", +] + +[[package]] name = "unicase" version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -642,24 +436,12 @@ dependencies = [ ] [[package]] -name = "vec-arena" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eafc1b9b2dfc6f5529177b62cf806484db55b32dc7c9658a118e11bbeb33061d" - -[[package]] name = "version_check" version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" [[package]] -name = "waker-fn" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" - -[[package]] name = "wasm-bindgen" version = "0.2.69" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -685,18 +467,6 @@ dependencies = [ ] [[package]] -name = "wasm-bindgen-futures" -version = "0.4.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fe9756085a84584ee9457a002b7cdfe0bfff169f45d2591d8be1345a6780e35" -dependencies = [ - "cfg-if 1.0.0", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] name = "wasm-bindgen-macro" version = "0.2.69" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -746,15 +516,6 @@ dependencies = [ ] [[package]] -name = "wepoll-sys" -version = "3.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fcb14dea929042224824779fbc82d9fab8d2e6d3cbc0ac404de8edf489e77ff" -dependencies = [ - "cc", -] - -[[package]] name = "winapi" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/Cargo.toml b/Cargo.toml @@ -11,8 +11,8 @@ license = "MIT/Apache-2.0" edition = "2018" [dependencies] -async-tls = { version = "0.11.0", default-features = false, features = ["server"] } -async-std = "1.5" +tokio-rustls = "0.22.0" +tokio = { version = "1.0", features = ["fs", "io-util", "net", "rt-multi-thread"] } env_logger = { version = "0.8", default-features = false, features = ["atty", "humantime", "termcolor"] } getopts = "0.2.21" log = "0.4" diff --git a/src/main.rs b/src/main.rs @@ -1,10 +1,9 @@ -use async_std::{ - io::prelude::*, +use tokio::{ + io::{AsyncReadExt, AsyncWriteExt}, net::{TcpListener, TcpStream}, - stream::StreamExt, - task, + runtime::Runtime, }; -use async_tls::{TlsAcceptor, server::TlsStream}; +use tokio_rustls::{TlsAcceptor, server::TlsStream}; use once_cell::sync::Lazy; use percent_encoding::{AsciiSet, CONTROLS, percent_decode_str, percent_encode}; use rustls::{ @@ -26,18 +25,17 @@ fn main() -> Result { if !ARGS.silent { env_logger::Builder::new().parse_filters("info").init(); } - task::block_on(async { + Runtime::new()?.block_on(async { let listener = TcpListener::bind(&ARGS.sock_addr).await?; - let mut incoming = listener.incoming(); log::info!("Listening on {}...", ARGS.sock_addr); - while let Some(Ok(stream)) = incoming.next().await { - task::spawn(async { + loop { + let (stream, _) = listener.accept().await?; + tokio::spawn(async { if let Err(e) = handle_request(stream).await { log::error!("{:?}", e); } }); } - Ok(()) }) } @@ -181,7 +179,7 @@ async fn send_response(url: Url, stream: &mut TlsStream<TcpStream>) -> Result { path.push(&*percent_decode_str(segment).decode_utf8()?); } } - if let Ok(metadata) = async_std::fs::metadata(&path).await { + if let Ok(metadata) = tokio::fs::metadata(&path).await { if metadata.is_dir() { if url.path().ends_with('/') || url.path().is_empty() { // if the path ends with a slash or the path is empty, the links will work the same @@ -199,7 +197,7 @@ async fn send_response(url: Url, stream: &mut TlsStream<TcpStream>) -> Result { } // Make sure the file opens successfully before sending the success header. - let mut file = match async_std::fs::File::open(&path).await { + let mut file = match tokio::fs::File::open(&path).await { Ok(file) => file, Err(e) => { send_header(stream, 51, &["Not found, sorry."]).await?; @@ -216,7 +214,7 @@ async fn send_response(url: Url, stream: &mut TlsStream<TcpStream>) -> Result { } // Send body. - async_std::io::copy(&mut file, stream).await?; + tokio::io::copy(&mut file, stream).await?; Ok(()) } @@ -228,10 +226,9 @@ async fn list_directory(stream: &mut TlsStream<TcpStream>, path: &Path) -> Resul log::info!("Listing directory {:?}", path); send_text_gemini_header(stream).await?; - let mut entries = async_std::fs::read_dir(path).await?; + let mut entries = tokio::fs::read_dir(path).await?; let mut lines = vec![]; - while let Some(entry) = entries.next().await { - let entry = entry?; + while let Some(entry) = entries.next_entry().await? { let mut name = entry.file_name().into_string().or(Err("Non-Unicode filename"))?; if name.starts_with('.') { continue;