Moved certificate into request, so this is no longer a breaking change

gemtext
Emi Tatsuo 2020-11-13 15:04:25 -05:00
parent 3547143860
commit eaee14d174
Signed by: Emi
GPG Key ID: 68FAB2E2E6DFC98B
4 changed files with 32 additions and 12 deletions

View File

@ -13,7 +13,7 @@ async fn main() -> Result<()> {
let users = Arc::<RwLock::<HashMap<CertBytes, String>>>::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<RwLock<HashMap<CertBytes, String>>>, request: Request, cert: Option<Certificate>) -> BoxFuture<'static, Result<Response>> {
fn handle_request(users: Arc<RwLock<HashMap<CertBytes, String>>>, request: Request) -> BoxFuture<'static, Result<Response>> {
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<RwLock<HashMap<CertBytes, String>>>, 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!(

View File

@ -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<Certificate>) -> BoxFuture<'static, Result<Response>> {
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?;

View File

@ -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<dyn Fn(Request, Option<Certificate>) -> HandlerResponse + Send + Sync>;
type Handler = Arc<dyn Fn(Request) -> HandlerResponse + Send + Sync>;
type HandlerResponse = BoxFuture<'static, Result<Response>>;
#[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<A: ToSocketAddrs> Builder<A> {
pub async fn serve<F>(self, handler: F) -> Result<()>
where
F: Fn(Request, Option<Certificate>) -> HandlerResponse + Send + Sync + 'static,
F: Fn(Request) -> HandlerResponse + Send + Sync + 'static,
{
let config = tls_config()?;

View File

@ -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<String>,
certificate: Option<Certificate>,
}
impl Request {
pub fn from_uri(mut uri: URIReference<'static>) -> Result<Self> {
pub fn from_uri(uri: URIReference<'static>) -> Result<Self> {
Self::with_certificate(uri, None)
}
pub fn with_certificate(
mut uri: URIReference<'static>,
certificate: Option<Certificate>
) -> Result<Self> {
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<Certificate>) {
self.certificate = cert;
}
pub fn certificate(&self) -> Option<&Certificate> {
self.certificate.as_ref()
}
}
impl ops::Deref for Request {