good_mitm_core/
handler.rs1use 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}