czh_http_server/
filter.rs1use 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;
12pub 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 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}