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 anyhow::*;
|
||||||
use log::LevelFilter;
|
use log::LevelFilter;
|
||||||
use northstar::{Server, Request, Response, GEMINI_PORT, Document};
|
use northstar::{Server, Response, GEMINI_PORT, Document};
|
||||||
use northstar::document::HeadingLevel::*;
|
use northstar::document::HeadingLevel::*;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
|
@ -9,14 +9,7 @@ async fn main() -> Result<()> {
|
||||||
.filter_module("northstar", LevelFilter::Debug)
|
.filter_module("northstar", LevelFilter::Debug)
|
||||||
.init();
|
.init();
|
||||||
|
|
||||||
Server::bind(("localhost", GEMINI_PORT))
|
let response: Response = Document::new()
|
||||||
.add_route("/",handle_request)
|
|
||||||
.serve()
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn handle_request(_request: Request) -> Result<Response> {
|
|
||||||
let response = Document::new()
|
|
||||||
.add_preformatted(include_str!("northstar_logo.txt"))
|
.add_preformatted(include_str!("northstar_logo.txt"))
|
||||||
.add_blank_line()
|
.add_blank_line()
|
||||||
.add_link("https://docs.rs/northstar", "Documentation")
|
.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",
|
"openssl req -x509 -nodes -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365",
|
||||||
))
|
))
|
||||||
.into();
|
.into();
|
||||||
Ok(response)
|
|
||||||
|
Server::bind(("localhost", GEMINI_PORT))
|
||||||
|
.add_route("/", response)
|
||||||
|
.serve()
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ use std::{
|
||||||
panic::{catch_unwind, AssertUnwindSafe},
|
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.
|
/// A struct representing something capable of handling a request.
|
||||||
///
|
///
|
||||||
|
@ -29,6 +29,7 @@ use crate::types::{Response, Request};
|
||||||
/// response is produced.
|
/// response is produced.
|
||||||
pub enum Handler {
|
pub enum Handler {
|
||||||
FnHandler(HandlerInner),
|
FnHandler(HandlerInner),
|
||||||
|
StaticHandler(Response),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Since we can't store train objects, we need to wrap fn handlers in a box
|
/// 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()
|
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.
|
/// A utility for catching unwinds on Futures.
|
||||||
///
|
///
|
||||||
/// This is adapted from the futures-rs CatchUnwind, in an effort to reduce the large
|
/// 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 {
|
impl<D: Borrow<Document>> From<D> for Response {
|
||||||
fn from(doc: D) -> Self {
|
fn from(doc: D) -> Self {
|
||||||
Self::document(doc)
|
Self::document(doc)
|
||||||
|
|
|
@ -10,6 +10,7 @@ use tokio::{
|
||||||
};
|
};
|
||||||
#[cfg(feature="serve_dir")]
|
#[cfg(feature="serve_dir")]
|
||||||
use crate::types::{Document, document::HeadingLevel::*};
|
use crate::types::{Document, document::HeadingLevel::*};
|
||||||
|
#[cfg(feature="serve_dir")]
|
||||||
use crate::types::Response;
|
use crate::types::Response;
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use tokio::time;
|
use tokio::time;
|
||||||
|
|
Loading…
Reference in a new issue