Skip to main content

sword_layers/cors/
layer.rs

1use super::CorsConfig;
2
3use axum::http::{HeaderName, HeaderValue, Method};
4use tower_http::cors::{Any, CorsLayer as TowerCorsLayer};
5
6/// ### CORS Layer
7///
8/// This struct represents the CORS Layer which
9/// handles Cross-Origin Resource Sharing configuration.
10///
11/// The layer is a wrapper around `tower_http::cors::CorsLayer`.
12/// Configures which origins, methods, headers, and credentials are allowed
13/// for cross-origin requests.
14pub struct CorsLayer;
15
16impl CorsLayer {
17    pub fn new(config: &CorsConfig) -> TowerCorsLayer {
18        let mut layer = TowerCorsLayer::new();
19
20        if let Some(allow_credentials) = config.allow_credentials {
21            layer = layer.allow_credentials(allow_credentials);
22        }
23
24        if let Some(origin) = &config.allow_origins {
25            if origin.iter().any(|o| o == "*") {
26                layer = layer.allow_origin(Any);
27            } else {
28                let parsed_origin: Vec<HeaderValue> = origin
29                    .iter()
30                    .filter_map(|o| HeaderValue::from_str(o).ok())
31                    .collect();
32
33                layer = layer.allow_origin(parsed_origin);
34            }
35        }
36
37        if let Some(methods) = &config.allow_methods {
38            if methods.iter().any(|m| m == "*") {
39                layer = layer.allow_methods(Any);
40            } else {
41                let parsed_methods: Vec<Method> =
42                    methods.iter().filter_map(|m| m.parse().ok()).collect();
43
44                layer = layer.allow_methods(parsed_methods);
45            }
46        }
47
48        if let Some(headers) = &config.allow_headers {
49            if headers.iter().any(|h| h == "*") {
50                layer = layer.allow_headers(Any);
51            } else {
52                let parsed_headers: Vec<HeaderName> =
53                    headers.iter().filter_map(|h| h.parse().ok()).collect();
54
55                layer = layer.allow_headers(parsed_headers);
56            }
57        }
58
59        if let Some(max_age) = &config.max_age {
60            layer = layer.max_age(max_age.parsed);
61        }
62
63        layer
64    }
65}