diff options
| -rw-r--r-- | Cargo.toml | 3 | ||||
| -rw-r--r-- | examples/windmark.rs | 3 | ||||
| -rw-r--r-- | src/handler.rs | 5 | ||||
| -rw-r--r-- | src/lib.rs | 12 | ||||
| -rw-r--r-- | src/response.rs | 10 |
5 files changed, 26 insertions, 7 deletions
@@ -33,3 +33,6 @@ log = "0.4.16" url = "2.2.2" regex = "1.5.5" matchit = "0.5.0" + +# MIME +tree_magic = "0.2.3" diff --git a/examples/windmark.rs b/examples/windmark.rs index ed6bc9f..6ceeaf7 100644 --- a/examples/windmark.rs +++ b/examples/windmark.rs @@ -111,6 +111,9 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> { .mount("/redirect", |_| { Response::PermanentRedirect("gemini://localhost/test".into()) }) + .mount("/file", |_| { + Response::SuccessFile(include_bytes!("../LICENSE")) + }) .run() .await } diff --git a/src/handler.rs b/src/handler.rs index e945dfc..071926c 100644 --- a/src/handler.rs +++ b/src/handler.rs @@ -18,8 +18,9 @@ use crate::{returnable::RouteContext, Response}; -pub type RouteResponse = fn(RouteContext<'_>) -> Response; -pub type ErrorResponse = fn(crate::returnable::ErrorContext<'_>) -> Response; +pub type RouteResponse = fn(RouteContext<'_>) -> Response<'_>; +pub type ErrorResponse = + fn(crate::returnable::ErrorContext<'_>) -> Response<'_>; pub type Callback = fn(&tokio::net::TcpStream, &url::Url, Option<&matchit::Params<'_, '_>>); pub type Partial = fn(RouteContext<'_>) -> String; @@ -314,13 +314,19 @@ impl Router { .write_all( format!( "{}{}\r\n{}", - response_status, + if response_status == 21 { + 20 + } else { + response_status + }, match response_status { - 20 => " text/gemini; charset=utf-8", - _ => &*content, + 20 => " text/gemini; charset=utf-8".to_string(), + 21 => tree_magic::from_u8(&*content.as_bytes()), + _ => (&*content).to_string(), }, match response_status { 20 => format!("{}{}{}", header, content, footer), + 21 => (&*content).to_string(), _ => "".to_string(), } ) diff --git a/src/response.rs b/src/response.rs index c7dbf88..d89dbf2 100644 --- a/src/response.rs +++ b/src/response.rs @@ -16,10 +16,11 @@ // Copyright (C) 2022-2022 Fuwn <[email protected]> // SPDX-License-Identifier: GPL-3.0-only -pub enum Response { +pub enum Response<'a> { Input(String), SensitiveInput(String), Success(String), + SuccessFile(&'a [u8]), TemporaryRedirect(String), PermanentRedirect(String), TemporaryFailure(String), @@ -38,7 +39,7 @@ pub enum Response { } pub(crate) fn to_value_set_status( - response: Response, + response: Response<'_>, status: &mut i32, ) -> String { match response { @@ -57,6 +58,11 @@ pub(crate) fn to_value_set_status( value } + Response::SuccessFile(value) => { + *status = 21; // Internal status code, not real. + + String::from_utf8(value.to_vec()).unwrap() + } Response::TemporaryRedirect(value) => { *status = 30; |