From eaee14d174275f8ef68896b3894341975d1239b8 Mon Sep 17 00:00:00 2001 From: Emi Tatsuo Date: Fri, 13 Nov 2020 15:04:25 -0500 Subject: [PATCH] Moved certificate into request, so this is no longer a breaking change --- examples/certificates.rs | 10 +++++----- examples/serve_dir.rs | 4 ++-- src/lib.rs | 10 ++++++---- src/types.rs | 20 +++++++++++++++++++- 4 files changed, 32 insertions(+), 12 deletions(-) diff --git a/examples/certificates.rs b/examples/certificates.rs index 8c4b59a..5842f1d 100644 --- a/examples/certificates.rs +++ b/examples/certificates.rs @@ -13,7 +13,7 @@ async fn main() -> Result<()> { let users = Arc::>>::default(); Server::bind(("0.0.0.0", GEMINI_PORT)) - .serve(move|req, cert| handle_request(users.clone(), req, cert)) + .serve(move|req| handle_request(users.clone(), req)) .await } @@ -24,12 +24,12 @@ 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>>, request: Request, cert: Option) -> BoxFuture<'static, Result> { +fn handle_request(users: Arc>>, request: Request) -> BoxFuture<'static, Result> { async move { - if let Some(Certificate(cert_bytes)) = cert { + 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) { + if let Some(user) = users_read.get(cert_bytes) { // The user has already registered Ok( Response::success(&gemini_mime()?)? @@ -42,7 +42,7 @@ fn handle_request(users: Arc>>, request: Reque // 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, username.to_owned()); + users_write.insert(cert_bytes.clone(), username.to_owned()); Ok( Response::success(&gemini_mime()?)? .with_body(format!( diff --git a/examples/serve_dir.rs b/examples/serve_dir.rs index 4d9fdbe..d4a6bb8 100644 --- a/examples/serve_dir.rs +++ b/examples/serve_dir.rs @@ -1,6 +1,6 @@ use anyhow::*; use futures::{future::BoxFuture, FutureExt}; -use northstar::{Server, Request, Response, GEMINI_PORT, Certificate}; +use northstar::{Server, Request, Response, GEMINI_PORT}; #[tokio::main] async fn main() -> Result<()> { @@ -9,7 +9,7 @@ async fn main() -> Result<()> { .await } -fn handle_request(request: Request, _cert: Option) -> BoxFuture<'static, Result> { +fn handle_request(request: Request) -> BoxFuture<'static, Result> { async move { let path = request.path_segments(); let response = northstar::util::serve_dir("public", &path).await?; diff --git a/src/lib.rs b/src/lib.rs index 6f7c873..3206a27 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,7 +26,7 @@ pub use rustls::Certificate; pub const REQUEST_URI_MAX_LEN: usize = 1024; pub const GEMINI_PORT: u16 = 1965; -type Handler = Arc) -> HandlerResponse + Send + Sync>; +type Handler = Arc HandlerResponse + Send + Sync>; type HandlerResponse = BoxFuture<'static, Result>; #[derive(Clone)] @@ -58,7 +58,7 @@ impl Server { let stream = self.tls_acceptor.accept(stream).await?; let mut stream = BufStream::new(stream); - let request = receive_request(&mut stream).await?; + let mut request = receive_request(&mut stream).await?; debug!("Client requested: {}", request.uri()); // Identify the client certificate from the tls stream. This is the first @@ -69,7 +69,9 @@ impl Server { .get_peer_certificates() .and_then(|mut v| if v.is_empty() {None} else {Some(v.remove(0))}); - let handler = (self.handler)(request, client_cert); + request.set_cert(client_cert); + + let handler = (self.handler)(request); let handler = AssertUnwindSafe(handler); let response = handler.catch_unwind().await @@ -98,7 +100,7 @@ impl Builder { pub async fn serve(self, handler: F) -> Result<()> where - F: Fn(Request, Option) -> HandlerResponse + Send + Sync + 'static, + F: Fn(Request) -> HandlerResponse + Send + Sync + 'static, { let config = tls_config()?; diff --git a/src/types.rs b/src/types.rs index 41d55c3..c0e9fb3 100644 --- a/src/types.rs +++ b/src/types.rs @@ -4,14 +4,23 @@ use mime::Mime; use percent_encoding::percent_decode_str; use tokio::{io::AsyncRead, fs::File}; use uriparse::URIReference; +use rustls::Certificate; pub struct Request { uri: URIReference<'static>, input: Option, + certificate: Option, } impl Request { - pub fn from_uri(mut uri: URIReference<'static>) -> Result { + pub fn from_uri(uri: URIReference<'static>) -> Result { + Self::with_certificate(uri, None) + } + + pub fn with_certificate( + mut uri: URIReference<'static>, + certificate: Option + ) -> Result { uri.normalize(); let input = match uri.query() { @@ -27,6 +36,7 @@ impl Request { Ok(Self { uri, input, + certificate, }) } @@ -46,6 +56,14 @@ impl Request { pub fn input(&self) -> Option<&str> { self.input.as_deref() } + + pub fn set_cert(&mut self, cert: Option) { + self.certificate = cert; + } + + pub fn certificate(&self) -> Option<&Certificate> { + self.certificate.as_ref() + } } impl ops::Deref for Request {