commit ce570fc8c43e2fe68964f1f9f15fc890ee682cf3
parent db5665b783c3f136f6005960fb1359ec824bebc2
Author: Matt Brubeck <mbrubeck@limpet.net>
Date: Thu, 21 May 2020 15:28:07 -0700
Auto-detect MIME types
Diffstat:
4 files changed, 125 insertions(+), 12 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
@@ -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",
@@ -95,6 +96,15 @@ 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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -142,6 +152,18 @@ dependencies = [
]
[[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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -250,7 +272,7 @@ dependencies = [
"futures-macro",
"futures-sink",
"futures-task",
- "memchr",
+ "memchr 2.3.3",
"pin-project",
"pin-utils",
"proc-macro-hack",
@@ -279,6 +301,15 @@ dependencies = [
]
[[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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -328,6 +359,15 @@ 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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -350,6 +390,15 @@ 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"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
@@ -417,6 +466,15 @@ dependencies = [
]
[[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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -433,12 +491,46 @@ 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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -501,6 +593,12 @@ dependencies = [
]
[[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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -574,6 +672,19 @@ dependencies = [
]
[[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"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
@@ -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]
diff --git a/README.md b/README.md
@@ -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/
diff --git a/src/main.rs b/src/main.rs
@@ -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) => {