forked from cadey/maj
62 lines
1.9 KiB
Rust
62 lines
1.9 KiB
Rust
|
/// A simple handler for disk based files. Will optionally chop off a prefix.
|
||
|
use super::{Handler as MajHandler, Request, Result};
|
||
|
use crate::Response;
|
||
|
use async_trait::async_trait;
|
||
|
use std::ffi::OsStr;
|
||
|
|
||
|
pub struct Handler {
|
||
|
chop_off: String,
|
||
|
base_dir: String,
|
||
|
}
|
||
|
|
||
|
impl Handler {
|
||
|
/// Serves static files from an OS directory with a given prefix chopped off.
|
||
|
pub fn new(chop_off: String, base_dir: String) -> Self {
|
||
|
Handler {
|
||
|
chop_off: chop_off,
|
||
|
base_dir: base_dir,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fn chop(&self, path: String) -> Option<String> {
|
||
|
if path.starts_with(&self.chop_off) {
|
||
|
path.strip_prefix(&self.chop_off).map(|val| val.to_string())
|
||
|
} else {
|
||
|
Some(path)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[async_trait]
|
||
|
impl MajHandler for Handler {
|
||
|
async fn handle(&self, r: Request) -> Result<Response> {
|
||
|
let mut path = std::path::PathBuf::from(&self.base_dir);
|
||
|
let mut url = r.url.clone();
|
||
|
url.set_path(&self.chop(r.url.path().to_string()).unwrap());
|
||
|
if let Some(segments) = r.url.path_segments() {
|
||
|
path.extend(segments);
|
||
|
}
|
||
|
|
||
|
if async_std::fs::metadata(&path).await?.is_dir() {
|
||
|
if url.as_str().ends_with('/') {
|
||
|
path.push("index.gmi");
|
||
|
} else {
|
||
|
// Send a redirect when the URL for a directory has no trailing slash.
|
||
|
return Ok(Response::perm_redirect(format!("{}/", url)));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
let mut file = async_std::fs::File::open(&path).await?;
|
||
|
let mut buf: Vec<u8> = Vec::new();
|
||
|
async_std::io::copy(&mut file, &mut buf).await?;
|
||
|
|
||
|
// Send header.
|
||
|
if path.extension() == Some(OsStr::new("gmi")) {
|
||
|
return Ok(Response::gemini(buf));
|
||
|
}
|
||
|
|
||
|
let mime = mime_guess::from_path(&path).first_or_octet_stream();
|
||
|
Ok(Response::with_body(mime.essence_str().to_string(), buf))
|
||
|
}
|
||
|
}
|