Changed the add_route API to allow the use of simpler, async handlers
This commit is contained in:
parent
54816e1f67
commit
29c831649d
|
@ -28,5 +28,4 @@ mime_guess = { version = "2.0.3", optional = true }
|
|||
|
||||
[dev-dependencies]
|
||||
env_logger = "0.8.1"
|
||||
futures-util = "0.3.7"
|
||||
tokio = { version = "0.3.1", features = ["macros", "rt-multi-thread", "sync"] }
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
use anyhow::*;
|
||||
use futures_core::future::BoxFuture;
|
||||
use futures_util::FutureExt;
|
||||
use log::LevelFilter;
|
||||
use tokio::sync::RwLock;
|
||||
use northstar::{Certificate, GEMINI_MIME, GEMINI_PORT, Request, Response, Server};
|
||||
|
@ -31,44 +29,42 @@ async fn main() -> Result<()> {
|
|||
/// selecting a username. They'll then get a message confirming their account creation.
|
||||
/// Any time this user visits the site in the future, they'll get a personalized welcome
|
||||
/// message.
|
||||
fn handle_request(users: Arc<RwLock<HashMap<CertBytes, String>>>, request: Request) -> BoxFuture<'static, Result<Response>> {
|
||||
async move {
|
||||
if let Some(Certificate(cert_bytes)) = request.certificate() {
|
||||
// The user provided a certificate
|
||||
let users_read = users.read().await;
|
||||
if let Some(user) = users_read.get(cert_bytes) {
|
||||
// The user has already registered
|
||||
async fn handle_request(users: Arc<RwLock<HashMap<CertBytes, String>>>, request: Request) -> Result<Response> {
|
||||
if let Some(Certificate(cert_bytes)) = request.certificate() {
|
||||
// The user provided a certificate
|
||||
let users_read = users.read().await;
|
||||
if let Some(user) = users_read.get(cert_bytes) {
|
||||
// The user has already registered
|
||||
Ok(
|
||||
Response::success_with_body(
|
||||
&GEMINI_MIME,
|
||||
format!("Welcome {}!", user)
|
||||
)
|
||||
)
|
||||
} else {
|
||||
// The user still needs to register
|
||||
drop(users_read);
|
||||
if let Some(query_part) = request.uri().query() {
|
||||
// The user provided some input (a username request)
|
||||
let username = query_part.as_str();
|
||||
let mut users_write = users.write().await;
|
||||
users_write.insert(cert_bytes.clone(), username.to_owned());
|
||||
Ok(
|
||||
Response::success_with_body(
|
||||
&GEMINI_MIME,
|
||||
format!("Welcome {}!", user)
|
||||
format!(
|
||||
"Your account has been created {}! Welcome!",
|
||||
username
|
||||
)
|
||||
)
|
||||
)
|
||||
} else {
|
||||
// The user still needs to register
|
||||
drop(users_read);
|
||||
if let Some(query_part) = request.uri().query() {
|
||||
// The user provided some input (a username request)
|
||||
let username = query_part.as_str();
|
||||
let mut users_write = users.write().await;
|
||||
users_write.insert(cert_bytes.clone(), username.to_owned());
|
||||
Ok(
|
||||
Response::success_with_body(
|
||||
&GEMINI_MIME,
|
||||
format!(
|
||||
"Your account has been created {}! Welcome!",
|
||||
username
|
||||
)
|
||||
)
|
||||
)
|
||||
} else {
|
||||
// The user didn't provide input, and should be prompted
|
||||
Response::input("What username would you like?")
|
||||
}
|
||||
// The user didn't provide input, and should be prompted
|
||||
Response::input("What username would you like?")
|
||||
}
|
||||
} else {
|
||||
// The user didn't provide a certificate
|
||||
Ok(Response::client_certificate_required())
|
||||
}
|
||||
}.boxed()
|
||||
} else {
|
||||
// The user didn't provide a certificate
|
||||
Ok(Response::client_certificate_required())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
use anyhow::*;
|
||||
use futures_core::future::BoxFuture;
|
||||
use futures_util::FutureExt;
|
||||
use log::LevelFilter;
|
||||
use northstar::{Server, Request, Response, GEMINI_PORT, Document};
|
||||
use northstar::document::HeadingLevel::*;
|
||||
|
@ -17,36 +15,33 @@ async fn main() -> Result<()> {
|
|||
.await
|
||||
}
|
||||
|
||||
fn handle_request(_request: Request) -> BoxFuture<'static, Result<Response>> {
|
||||
async move {
|
||||
let mut document = Document::new();
|
||||
async fn handle_request(_request: Request) -> Result<Response> {
|
||||
let mut document = Document::new();
|
||||
|
||||
document
|
||||
.add_preformatted(include_str!("northstar_logo.txt"))
|
||||
.add_blank_line()
|
||||
.add_link("https://docs.rs/northstar", "Documentation")
|
||||
.add_link("https://github.com/panicbit/northstar", "GitHub")
|
||||
.add_blank_line()
|
||||
.add_heading(H1, "Usage")
|
||||
.add_blank_line()
|
||||
.add_text("Add the latest version of northstar to your `Cargo.toml`.")
|
||||
.add_blank_line()
|
||||
.add_heading(H2, "Manually")
|
||||
.add_blank_line()
|
||||
.add_preformatted_with_alt("toml", r#"northstar = "0.3.0" # check crates.io for the latest version"#)
|
||||
.add_blank_line()
|
||||
.add_heading(H2, "Automatically")
|
||||
.add_blank_line()
|
||||
.add_preformatted_with_alt("sh", "cargo add northstar")
|
||||
.add_blank_line()
|
||||
.add_heading(H1, "Generating a key & certificate")
|
||||
.add_blank_line()
|
||||
.add_preformatted_with_alt("sh", concat!(
|
||||
"mkdir cert && cd cert\n",
|
||||
"openssl req -x509 -nodes -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365",
|
||||
));
|
||||
document
|
||||
.add_preformatted(include_str!("northstar_logo.txt"))
|
||||
.add_blank_line()
|
||||
.add_link("https://docs.rs/northstar", "Documentation")
|
||||
.add_link("https://github.com/panicbit/northstar", "GitHub")
|
||||
.add_blank_line()
|
||||
.add_heading(H1, "Usage")
|
||||
.add_blank_line()
|
||||
.add_text("Add the latest version of northstar to your `Cargo.toml`.")
|
||||
.add_blank_line()
|
||||
.add_heading(H2, "Manually")
|
||||
.add_blank_line()
|
||||
.add_preformatted_with_alt("toml", r#"northstar = "0.3.0" # check crates.io for the latest version"#)
|
||||
.add_blank_line()
|
||||
.add_heading(H2, "Automatically")
|
||||
.add_blank_line()
|
||||
.add_preformatted_with_alt("sh", "cargo add northstar")
|
||||
.add_blank_line()
|
||||
.add_heading(H1, "Generating a key & certificate")
|
||||
.add_blank_line()
|
||||
.add_preformatted_with_alt("sh", concat!(
|
||||
"mkdir cert && cd cert\n",
|
||||
"openssl req -x509 -nodes -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365",
|
||||
));
|
||||
|
||||
Ok(Response::document(document))
|
||||
}
|
||||
.boxed()
|
||||
Ok(Response::document(document))
|
||||
}
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
use anyhow::*;
|
||||
use futures_core::future::BoxFuture;
|
||||
use futures_util::FutureExt;
|
||||
use log::LevelFilter;
|
||||
use northstar::{Document, document::HeadingLevel, Request, Response, GEMINI_PORT};
|
||||
|
||||
|
@ -18,25 +16,19 @@ async fn main() -> Result<()> {
|
|||
.await
|
||||
}
|
||||
|
||||
fn handle_base(_: Request) -> BoxFuture<'static, Result<Response>> {
|
||||
async fn handle_base(_: Request) -> Result<Response> {
|
||||
let doc = generate_doc("base");
|
||||
async move {
|
||||
Ok(Response::document(doc))
|
||||
}.boxed()
|
||||
Ok(Response::document(doc))
|
||||
}
|
||||
|
||||
fn handle_short(_: Request) -> BoxFuture<'static, Result<Response>> {
|
||||
async fn handle_short(_: Request) -> Result<Response> {
|
||||
let doc = generate_doc("short");
|
||||
async move {
|
||||
Ok(Response::document(doc))
|
||||
}.boxed()
|
||||
Ok(Response::document(doc))
|
||||
}
|
||||
|
||||
fn handle_long(_: Request) -> BoxFuture<'static, Result<Response>> {
|
||||
async fn handle_long(_: Request) -> Result<Response> {
|
||||
let doc = generate_doc("long");
|
||||
async move {
|
||||
Ok(Response::document(doc))
|
||||
}.boxed()
|
||||
Ok(Response::document(doc))
|
||||
}
|
||||
|
||||
fn generate_doc(route_name: &str) -> Document {
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
use anyhow::*;
|
||||
use futures_core::future::BoxFuture;
|
||||
use futures_util::FutureExt;
|
||||
use log::LevelFilter;
|
||||
use northstar::{Server, Request, Response, GEMINI_PORT};
|
||||
|
||||
|
@ -16,12 +14,9 @@ async fn main() -> Result<()> {
|
|||
.await
|
||||
}
|
||||
|
||||
fn handle_request(request: Request) -> BoxFuture<'static, Result<Response>> {
|
||||
async move {
|
||||
let path = request.path_segments();
|
||||
let response = northstar::util::serve_dir("public", &path).await?;
|
||||
async fn handle_request(request: Request) -> Result<Response> {
|
||||
let path = request.path_segments();
|
||||
let response = northstar::util::serve_dir("public", &path).await?;
|
||||
|
||||
Ok(response)
|
||||
}
|
||||
.boxed()
|
||||
Ok(response)
|
||||
}
|
||||
|
|
10
src/lib.rs
10
src/lib.rs
|
@ -8,7 +8,7 @@ use std::{
|
|||
path::PathBuf,
|
||||
time::Duration,
|
||||
};
|
||||
use futures_core::future::BoxFuture;
|
||||
use futures_core::future::{BoxFuture, Future};
|
||||
use tokio::{
|
||||
prelude::*,
|
||||
io::{self, BufStream},
|
||||
|
@ -290,11 +290,13 @@ impl<A: ToSocketAddrs> Builder<A> {
|
|||
/// "endpoint". Entering a relative or malformed path will result in a panic.
|
||||
///
|
||||
/// For more information about routing mechanics, see the docs for [`RoutingNode`].
|
||||
pub fn add_route<H>(mut self, path: &'static str, handler: H) -> Self
|
||||
pub fn add_route<F, H>(mut self, path: &'static str, handler: H) -> Self
|
||||
where
|
||||
H: Fn(Request) -> HandlerResponse + Send + Sync + 'static,
|
||||
H: Send + Sync + 'static + Fn(Request) -> F,
|
||||
F: Send + Sync + 'static + Future<Output = Result<Response>>
|
||||
{
|
||||
self.routes.add_route(path, Arc::new(handler));
|
||||
let wrapped = Arc::new(move|req| Box::pin((handler)(req)) as HandlerResponse);
|
||||
self.routes.add_route(path, wrapped);
|
||||
self
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue