medullah_web/http/
kernel.rs

1use crate::enums::ResponseCode;
2use crate::helpers::responder::Responder;
3use crate::http::middlewares::Middleware;
4use crate::http::Method;
5use log::info;
6use ntex::http::header;
7use ntex::web::middleware::Logger;
8use ntex::web::ServiceConfig;
9use ntex::{web, web::Route as NtexRoute};
10use ntex_cors::Cors;
11
12pub struct Controller {
13    pub path: String,
14    pub handler: fn(cfg: &mut ServiceConfig),
15}
16
17pub struct Route {
18    pub prefix: String,
19    pub middlewares: Vec<Middleware>,
20    pub controllers: Vec<Controller>,
21}
22
23pub fn register_routes(config: &mut ServiceConfig, routes: Vec<Route>) {
24    log::debug!("discovering routes...");
25
26    for route in routes {
27        for controller in &route.controllers {
28            let path = route.prefix.as_str().to_owned() + controller.path.as_str();
29            log::debug!(
30                "route group: {}",
31                if path.is_empty() { "/" } else { path.as_str() }
32            );
33
34            if path.is_empty() {
35                config.service(web::scope("").configure(controller.handler));
36            } else if !route.middlewares.is_empty() {
37                let total = route.middlewares.len();
38
39                if total == 1 {
40                    let scope = web::scope(path.as_str())
41                        .wrap(route.middlewares.first().unwrap().middleware())
42                        .configure(controller.handler);
43                    config.service(scope);
44                } else if total == 2 {
45                    let scope = web::scope(path.as_str())
46                        .wrap(route.middlewares.first().unwrap().middleware())
47                        .wrap(route.middlewares.last().unwrap().middleware())
48                        .configure(controller.handler);
49                    config.service(scope);
50                } else {
51                    let scope = web::scope(path.as_str())
52                        .wrap(route.middlewares.first().unwrap().middleware())
53                        .wrap(route.middlewares.get(1).unwrap().middleware())
54                        .wrap(route.middlewares.last().unwrap().middleware())
55                        .configure(controller.handler);
56                    config.service(scope);
57                }
58            } else {
59                config.service(web::scope(path.as_str()).configure(controller.handler));
60            }
61        }
62    }
63
64    log::debug!("route discovery finished :)");
65}
66
67pub fn setup_logger() -> Logger {
68    Logger::default()
69        .exclude("/favicon.ico")
70        .exclude("/system/docker-health-check")
71}
72
73pub fn setup_cors(origins: Vec<String>, methods: Vec<Method>) -> Cors {
74    let mut cors = Cors::new().send_wildcard();
75
76    for origin in origins {
77        info!("registering cors origin: {origin}...");
78
79        // convert "*" to ntex-compatible value
80        let origin = match origin == "*" {
81            false => origin,
82            true => "All".to_string(),
83        };
84
85        cors = cors.allowed_origin(origin.as_str());
86    }
87
88    let allowed_methods = match methods.is_empty() {
89        false => methods,
90        true => vec![
91            Method::GET,
92            Method::POST,
93            Method::PUT,
94            Method::PATCH,
95            Method::DELETE,
96            Method::OPTIONS,
97        ],
98    };
99
100    cors.allowed_methods(allowed_methods)
101        .allowed_headers(vec![header::AUTHORIZATION, header::ACCEPT])
102        .allowed_header(header::CONTENT_TYPE)
103        .max_age(3600)
104}
105
106pub fn ntex_default_service() -> NtexRoute {
107    web::to(|| async {
108        Responder::message("Requested Resource(s) Not Found", ResponseCode::NotFound)
109    })
110}
111
112pub fn register_middlewares(_config: &mut ServiceConfig) {
113    // for middleware in middlewares() {
114    // }
115}