pub mod make_cors_middleware;
use anyhow::Error;
use futures::Future;
use hyper::{Body, Request, Response};
use std::convert::TryFrom;
use std::pin::Pin;
use std::sync::Arc;
use crate::config::Config;
use self::make_cors_middleware::make_cors_middleware;
pub type MiddlewareBefore = Box<dyn Fn(&mut Request<Body>) + Send + Sync>;
pub type MiddlewareAfter = Box<dyn Fn(Arc<Request<Body>>, &mut Response<Body>) + Send + Sync>;
pub type Handler = Box<
dyn Fn(Arc<Request<Body>>) -> Pin<Box<dyn Future<Output = Response<Body>> + Send + Sync>>
+ Send
+ Sync,
>;
pub struct Middleware {
before: Vec<MiddlewareBefore>,
after: Vec<MiddlewareAfter>,
}
impl Middleware {
#[allow(dead_code)]
pub fn before(&mut self, middleware: MiddlewareBefore) {
self.before.push(middleware);
}
pub fn after(&mut self, middleware: MiddlewareAfter) {
self.after.push(middleware);
}
pub async fn handle(&self, mut request: Request<Body>, handler: Handler) -> Response<Body> {
for fx in self.before.iter() {
fx(&mut request);
}
let request = Arc::new(request);
let mut response = handler(Arc::clone(&request)).await;
for fx in self.after.iter() {
fx(Arc::clone(&request), &mut response);
}
response
}
}
impl Default for Middleware {
fn default() -> Self {
Middleware {
before: Vec::new(),
after: Vec::new(),
}
}
}
impl TryFrom<Arc<Config>> for Middleware {
type Error = Error;
fn try_from(config: Arc<Config>) -> Result<Self, Self::Error> {
let mut middleware = Middleware::default();
if let Some(cors_config) = config.cors() {
let cors_middleware = make_cors_middleware(cors_config);
middleware.after(cors_middleware);
}
Ok(middleware)
}
}