Added a static handler type. Impl AsRef<Body> for Response
im so tired i havent slept enough in so long but also i havent done any productive work like do you think im using this project as an excuse or like a bad coping mechanism for my mental health or something like that cause thats what its starting to feel like
This commit is contained in:
parent
7990739884
commit
c3d7381860
|
@ -1,6 +1,6 @@
|
|||
use anyhow::*;
|
||||
use log::LevelFilter;
|
||||
use northstar::{Server, Request, Response, GEMINI_PORT, Document};
|
||||
use northstar::{Server, Response, GEMINI_PORT, Document};
|
||||
use northstar::document::HeadingLevel::*;
|
||||
|
||||
#[tokio::main]
|
||||
|
@ -9,14 +9,7 @@ async fn main() -> Result<()> {
|
|||
.filter_module("northstar", LevelFilter::Debug)
|
||||
.init();
|
||||
|
||||
Server::bind(("localhost", GEMINI_PORT))
|
||||
.add_route("/",handle_request)
|
||||
.serve()
|
||||
.await
|
||||
}
|
||||
|
||||
async fn handle_request(_request: Request) -> Result<Response> {
|
||||
let response = Document::new()
|
||||
let response: Response = Document::new()
|
||||
.add_preformatted(include_str!("northstar_logo.txt"))
|
||||
.add_blank_line()
|
||||
.add_link("https://docs.rs/northstar", "Documentation")
|
||||
|
@ -41,5 +34,9 @@ async fn handle_request(_request: Request) -> Result<Response> {
|
|||
"openssl req -x509 -nodes -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365",
|
||||
))
|
||||
.into();
|
||||
Ok(response)
|
||||
|
||||
Server::bind(("localhost", GEMINI_PORT))
|
||||
.add_route("/", response)
|
||||
.serve()
|
||||
.await
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ use std::{
|
|||
panic::{catch_unwind, AssertUnwindSafe},
|
||||
};
|
||||
|
||||
use crate::types::{Response, Request};
|
||||
use crate::{Document, types::{Body, Response, Request}};
|
||||
|
||||
/// A struct representing something capable of handling a request.
|
||||
///
|
||||
|
@ -29,6 +29,7 @@ use crate::types::{Response, Request};
|
|||
/// response is produced.
|
||||
pub enum Handler {
|
||||
FnHandler(HandlerInner),
|
||||
StaticHandler(Response),
|
||||
}
|
||||
|
||||
/// Since we can't store train objects, we need to wrap fn handlers in a box
|
||||
|
@ -57,6 +58,26 @@ impl Handler {
|
|||
Response::server_error("").unwrap()
|
||||
})
|
||||
},
|
||||
Self::StaticHandler(response) => {
|
||||
let body = response.as_ref();
|
||||
match body {
|
||||
None => Response::new(response.header().clone()),
|
||||
Some(Body::Bytes(bytes)) => {
|
||||
Response::new(response.header().clone())
|
||||
.with_body(bytes.clone())
|
||||
},
|
||||
_ => {
|
||||
error!(concat!(
|
||||
"Cannot construct a static handler with a reader-based body! ",
|
||||
" We're sending a response so that the client doesn't crash, but",
|
||||
" given that this is a release build you should really fix this."
|
||||
));
|
||||
Response::server_error(
|
||||
"Very bad server error, go tell the sysadmin to look at the logs."
|
||||
).unwrap()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -81,6 +102,44 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
// We tolerate a fallible `impl From` because this is *really* not the kind of thing the
|
||||
// user should be catching in runtime.
|
||||
#[allow(clippy::fallible_impl_from)]
|
||||
impl From<Response> for Handler {
|
||||
/// Serve an unchanging response
|
||||
///
|
||||
/// Any and all requests to this handler will be responded to with the same response,
|
||||
/// no matter what. This is good for static content that is provided by your app.
|
||||
/// For serving files & directories, try looking at creating a handler from a path
|
||||
///
|
||||
/// ## Panics
|
||||
/// This response type **CANNOT** be created using Responses with [`Reader`] bodies.
|
||||
/// Attempting to do this will cause a panic. Don't.
|
||||
///
|
||||
/// [`Reader`]: Body::Reader
|
||||
fn from(response: Response) -> Self {
|
||||
#[cfg(debug_assertions)] {
|
||||
// We have another check once the handler is actually called that is not
|
||||
// disabled for release builds
|
||||
if let Some(Body::Reader(_)) = response.as_ref() {
|
||||
panic!("Cannot construct a static handler with a reader-based body");
|
||||
}
|
||||
}
|
||||
Self::StaticHandler(response)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Document> for Handler {
|
||||
/// Serve an unchanging response, shorthand for From<Response>
|
||||
///
|
||||
/// This document will be sent in response to any requests that arrive at this
|
||||
/// handler. As with all documents, this will be a successful response with a
|
||||
/// `text/gemini` MIME.
|
||||
fn from(doc: &Document) -> Self {
|
||||
Self::StaticHandler(doc.into())
|
||||
}
|
||||
}
|
||||
|
||||
/// A utility for catching unwinds on Futures.
|
||||
///
|
||||
/// This is adapted from the futures-rs CatchUnwind, in an effort to reduce the large
|
||||
|
|
|
@ -96,6 +96,18 @@ impl Response {
|
|||
}
|
||||
}
|
||||
|
||||
impl AsRef<Option<Body>> for Response {
|
||||
fn as_ref(&self) -> &Option<Body> {
|
||||
&self.body
|
||||
}
|
||||
}
|
||||
|
||||
impl AsMut<Option<Body>> for Response {
|
||||
fn as_mut(&mut self) -> &mut Option<Body> {
|
||||
&mut self.body
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Borrow<Document>> From<D> for Response {
|
||||
fn from(doc: D) -> Self {
|
||||
Self::document(doc)
|
||||
|
|
|
@ -10,6 +10,7 @@ use tokio::{
|
|||
};
|
||||
#[cfg(feature="serve_dir")]
|
||||
use crate::types::{Document, document::HeadingLevel::*};
|
||||
#[cfg(feature="serve_dir")]
|
||||
use crate::types::Response;
|
||||
use std::future::Future;
|
||||
use tokio::time;
|
||||
|
|
Loading…
Reference in a new issue