czh_http_server/
filter.rs

1use std::collections::HashMap;
2
3use crate::{request::HttpRequest, response::HttpResponse};
4
5pub struct FilterChain {
6    filters: HashMap<String, Vec<Filter>>,
7}
8pub type FilterHandler = dyn Fn(HttpRequest, HttpResponse) -> Option<(HttpRequest, HttpResponse)>
9    + Send
10    + Sync
11    + 'static;
12// pub type FilterHandler = Box<dyn Fn(HttpRequest,HttpResponse) -> Option<(HttpRequest,HttpResponse)> + Send + Sync + 'static>;
13pub struct Filter(Box<FilterHandler>);
14
15impl Filter {
16    pub fn new(
17        f: impl Fn(HttpRequest, HttpResponse) -> Option<(HttpRequest, HttpResponse)>
18            + Send
19            + Sync
20            + 'static,
21    ) -> Filter {
22        Filter(Box::new(f))
23    }
24    // (
25    //     HttpRequest,
26    //     HttpResponse
27    pub fn do_filter(
28        &self,
29        request: HttpRequest,
30        response: HttpResponse,
31    ) -> Option<(HttpRequest, HttpResponse)> {
32        self.0(request, response)
33    }
34}
35
36impl FilterChain {
37    pub fn new() -> FilterChain {
38        FilterChain {
39            filters: HashMap::new(),
40        }
41    }
42    pub fn add_filter(&mut self, filter_handler: Filter, match_url: &str) {
43        if let Some(filters) = self.filters.get_mut(match_url) {
44            filters.push(filter_handler);
45        } else {
46            self.filters
47                .insert(match_url.to_string(), vec![filter_handler]);
48        }
49    }
50    pub fn exec(
51        &self,
52        request: HttpRequest,
53        response: HttpResponse,
54    ) -> Option<(HttpRequest, HttpResponse)> {
55        let mut req = request;
56        let mut res = response;
57        let url = req.url().to_string();
58        for (_, handlers) in self
59            .filters
60            .iter()
61            .filter(|(key, _)| key.len() <= url.len() && url.contains(key.as_str()))
62        {
63            for ele in handlers {
64               if let Some((req_, res_)) = ele.do_filter(req, res) {
65                   req = req_;
66                   res = res_;
67               }else {
68                return None
69               }
70            }
71        }
72        Some((req, res))
73    }
74}