1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
use http::{Request, Response};
use hyper::Body;
use std::convert::TryFrom;
use std::sync::Arc;
use tokio::sync::Mutex;
use crate::addon::cors::Cors;
use crate::config::cors::CorsConfig;
use super::MiddlewareAfter;
/// Creates a CORS middleware with the configuration provided and returns it.
/// The configured headers will be appended to every HTTP Response before
/// sending such response back to the client (After Middleware)
///
/// CORS headers for every response are built on server initialization and
/// then are "appended" to Response headers on every response.
///
/// # Panics
///
/// Panics if a CORS config is not defined for the `Config` instance provided.
/// (`Config.cors` is `None`).
/// `make_cors_middlware` should only be called when a `CorsConfig` is defined.
///
/// Also panics if any CORS header value is not a valid UTF-8 string
pub fn make_cors_middleware(cors_config: CorsConfig) -> MiddlewareAfter {
let cors = Cors::try_from(cors_config).unwrap();
let cors_headers = cors.make_http_headers();
Box::new(
move |_: Arc<Mutex<Request<Body>>>, response: Arc<Mutex<Response<Body>>>| {
let cors_headers = cors_headers.clone();
let response = Arc::clone(&response);
Box::pin(async move {
let mut response = response.lock().await;
let headers = response.headers_mut();
cors_headers.iter().for_each(|(header, value)| {
headers.append(header, value.to_owned());
});
Ok(())
})
},
)
}