Auto-detect MIME types

This commit is contained in:
Matt Brubeck 2020-05-21 15:28:07 -07:00
parent db5665b783
commit ce570fc8c4
4 changed files with 125 additions and 12 deletions

117
Cargo.lock generated
View file

@ -2,12 +2,13 @@
# It is not intended for manual editing.
[[package]]
name = "agate"
version = "1.0.1"
version = "1.1.0"
dependencies = [
"async-std",
"async-tls",
"lazy_static",
"rustls",
"tree_magic",
"url",
]
@ -26,7 +27,7 @@ dependencies = [
"futures-timer",
"kv-log-macro",
"log",
"memchr",
"memchr 2.3.3",
"mio",
"mio-uds",
"num_cpus",
@ -94,6 +95,15 @@ version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]]
name = "cloudabi"
version = "0.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
dependencies = [
"bitflags",
]
[[package]]
name = "crossbeam-channel"
version = "0.4.2"
@ -141,6 +151,18 @@ dependencies = [
"lazy_static",
]
[[package]]
name = "fixedbitset"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d"
[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "fuchsia-zircon"
version = "0.3.3"
@ -250,7 +272,7 @@ dependencies = [
"futures-macro",
"futures-sink",
"futures-task",
"memchr",
"memchr 2.3.3",
"pin-project",
"pin-utils",
"proc-macro-hack",
@ -278,6 +300,15 @@ dependencies = [
"unicode-normalization",
]
[[package]]
name = "indexmap"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "076f042c5b7b98f31d205f1249267e12a6518c1481e9dae9764af19b707d2292"
dependencies = [
"autocfg",
]
[[package]]
name = "iovec"
version = "0.1.4"
@ -327,6 +358,15 @@ version = "0.2.70"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3baa92041a6fec78c687fa0cc2b3fae8884f743d672cf551bed1d6dac6988d0f"
[[package]]
name = "lock_api"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75"
dependencies = [
"scopeguard",
]
[[package]]
name = "log"
version = "0.4.8"
@ -348,6 +388,15 @@ version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
[[package]]
name = "memchr"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a"
dependencies = [
"libc",
]
[[package]]
name = "memchr"
version = "2.3.3"
@ -416,6 +465,15 @@ dependencies = [
"winapi 0.3.8",
]
[[package]]
name = "nom"
version = "3.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05aec50c70fd288702bcd93284a8444607f3292dbdf2a30de5ea5dcdbe72287b"
dependencies = [
"memchr 1.0.2",
]
[[package]]
name = "num_cpus"
version = "1.13.0"
@ -432,12 +490,46 @@ version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b631f7e854af39a1739f401cf34a8a013dfe09eac4fa4dba91e9768bd28168d"
[[package]]
name = "parking_lot"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e"
dependencies = [
"lock_api",
"parking_lot_core",
]
[[package]]
name = "parking_lot_core"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3"
dependencies = [
"cfg-if",
"cloudabi",
"libc",
"redox_syscall",
"smallvec",
"winapi 0.3.8",
]
[[package]]
name = "percent-encoding"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
[[package]]
name = "petgraph"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29c127eea4a29ec6c85d153c59dc1213f33ec74cead30fe4730aecc88cc1fd92"
dependencies = [
"fixedbitset",
"indexmap",
]
[[package]]
name = "pin-project"
version = "0.4.17"
@ -500,6 +592,12 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "redox_syscall"
version = "0.1.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
[[package]]
name = "ring"
version = "0.16.13"
@ -573,6 +671,19 @@ dependencies = [
"unicode-xid",
]
[[package]]
name = "tree_magic"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1d99367ce3e553a84738f73bd626ccca541ef90ae757fdcdc4cbe728e6cb629"
dependencies = [
"fnv",
"lazy_static",
"nom",
"parking_lot",
"petgraph",
]
[[package]]
name = "unicode-bidi"
version = "0.3.4"

View file

@ -1,6 +1,6 @@
[package]
name = "agate"
version = "1.0.1"
version = "1.1.0"
authors = ["Matt Brubeck <mbrubeck@limpet.net>"]
description = "Very simple server for the Gemini hypertext protocol"
keywords = ["server", "gemini", "hypertext", "internet", "protocol"]
@ -15,6 +15,7 @@ async-tls = "0.7.0"
async-std = "1.5"
lazy_static = "1.4"
rustls = "0.17.0"
tree_magic = "0.2.3"
url = "2.1"
[profile.release]

View file

@ -29,7 +29,7 @@ openssl req -x509 -newkey rsa:4096 -keyout key.rsa -out cert.pem \
agate localhost:1965 path/to/content/ cert.pem key.rsa
```
When a client requests the URL `gemini://example.com/foo/bar`, Agate will respond with the file at `path/to/content/foo/bar`. If there is a directory at that path, Agate will look for a file named `index.gemini` inside that directory. Currently, Agate sends all responses with the `text/gemini` MIME type. (Support for other MIME types may be added in the future.)
When a client requests the URL `gemini://example.com/foo/bar`, Agate will respond with the file at `path/to/content/foo/bar`. If there is a directory at that path, Agate will look for a file named `index.gemini` inside that directory.
[Gemini]: https://gemini.circumlunar.space/
[Rust]: https://www.rust-lang.org/

View file

@ -8,12 +8,7 @@ use {
},
async_tls::{TlsAcceptor, server::TlsStream},
lazy_static::lazy_static,
std::{
error::Error,
fs::File,
io::BufReader,
sync::Arc,
},
std::{error::Error, ffi::OsStr, fs::File, io::BufReader, sync::Arc},
url::Url,
};
@ -118,7 +113,13 @@ async fn get(url: &Url, stream: &mut TlsStream<TcpStream>) -> Result {
}
match async_std::fs::read(&path).await {
Ok(body) => {
stream.write_all(b"20 text/gemini\r\n").await?;
if path.extension() == Some(OsStr::new("gemini")) {
stream.write_all(b"20 text/gemini\r\n").await?;
} else {
let mime = tree_magic::from_u8(&body);
let header = format!("20 {}\r\n", mime);
stream.write_all(header.as_bytes()).await?;
}
stream.write_all(&body).await?;
}
Err(e) => {