good_mitm_core/
handler.rs

1use async_trait::async_trait;
2use hyper::{Body, Request, Response};
3use std::{
4    marker::PhantomData,
5    sync::{Arc, RwLock},
6};
7use wildmatch::WildMatch;
8
9use crate::mitm::{HttpContext, RequestOrResponse};
10
11pub trait CustomContextData: Clone + Default + Send + Sync + 'static {}
12
13#[async_trait]
14pub trait HttpHandler<D: CustomContextData>: Clone + Send + Sync + 'static {
15    async fn handle_request(
16        &self,
17        _ctx: &mut HttpContext<D>,
18        req: Request<Body>,
19    ) -> RequestOrResponse {
20        RequestOrResponse::Request(req)
21    }
22
23    async fn handle_response(
24        &self,
25        _ctx: &mut HttpContext<D>,
26        res: Response<Body>,
27    ) -> Response<Body> {
28        res
29    }
30}
31
32#[derive(Clone, Default)]
33pub struct MitmFilter<D: CustomContextData> {
34    filters: Arc<RwLock<Vec<WildMatch>>>,
35
36    _custom_contex_data: PhantomData<D>,
37}
38
39impl<D: CustomContextData> MitmFilter<D> {
40    pub fn new(filters: Vec<String>) -> Self {
41        let filters = filters.iter().map(|f| WildMatch::new(f)).collect();
42        Self {
43            filters: Arc::new(RwLock::new(filters)),
44            ..Default::default()
45        }
46    }
47
48    pub async fn filter(&self, _ctx: &HttpContext<D>, req: &Request<Body>) -> bool {
49        let host = req.uri().host().unwrap_or_default();
50        let list = self.filters.read().unwrap();
51        for m in list.iter() {
52            if m.matches(host) {
53                return true;
54            }
55        }
56        false
57    }
58}