product-os-proxy 0.0.17

Product OS : Proxy builds on the work of hudsucker, taking it to the next level with a man-in-the-middle proxy server that can tunnel traffic through a VPN utilising Product OS : VPN.
use std::sync::Arc;
pub use product_os_request::ProductOSResponse;
pub use product_os_server::{BeforeResult, ProductOSMiddleware, ProductOSMiddlewareAsync, RequestData};
pub use product_os_server::{Request, Response};

use async_trait::async_trait;
use hyper_tungstenite::tungstenite::Message;
use product_os_http_body::BodyBytes as Body;

use crate::mitm;


#[derive(Clone)]
pub struct ProxyMiddleware {
    middleware_handler: Arc<dyn ProductOSMiddlewareAsync>
}

impl ProxyMiddleware {
    pub fn new(middleware_handler: Arc<dyn ProductOSMiddlewareAsync>) -> Self {
        Self {
            middleware_handler
        }
    }

    pub fn default() -> Self {
        Self {
            middleware_handler: Arc::new(DefaultAsyncMiddleware::new())
        }
    }
}

#[async_trait]
impl mitm::HttpHandler for ProxyMiddleware {
    async fn handle_request(
        &mut self,
        _ctx: &mitm::HttpContext,
        request: Request<Body>,
    ) -> mitm::RequestOrResponse {
        match self.middleware_handler.before(request).await {
            BeforeResult::Result(req) => {
                mitm::RequestOrResponse::Request(req)
            }
            BeforeResult::Bypass(res) => {
                mitm::RequestOrResponse::Response(res)
            }
        }
    }

    async fn handle_response(
        &mut self,
        _ctx: &mitm::HttpContext,
        request: Request<Body>,
        response: Response<Body>
    ) -> Response<Body> {
        let request_data = RequestData {
            method: product_os_request::Method::from_http_method(&request.method()),
            headers: request.headers().clone(),
            uri: request.uri().clone()
        };

        self.middleware_handler.after(response, request_data).await
    }

    #[cfg(feature = "vpn")]
    async fn handle_product_os_response(
        &mut self,
        _ctx: &mitm::HttpContext,
        request: Request<Body>,
        response: ProductOSResponse<Body>
    ) -> Response<Body> {
        let request_data = RequestData {
            method: product_os_request::Method::from_http_method(&request.method()),
            headers: request.headers().clone(),
            uri: request.uri().clone()
        };

        self.middleware_handler.after_product_os_response(response, request_data).await
    }
}

#[async_trait]
impl mitm::WebSocketHandler for ProxyMiddleware {
    async fn handle_message(&mut self, _ctx: &mitm::WebSocketContext, message: Message) -> Option<Message> {
        Some(message)
    }
}



pub struct DefaultAsyncMiddleware {}

impl DefaultAsyncMiddleware {
    pub fn new() -> Self {
        Self {}
    }
}

impl ProductOSMiddleware for DefaultAsyncMiddleware {}

#[async_trait]
impl ProductOSMiddlewareAsync for DefaultAsyncMiddleware {
    async fn before(&self, request: Request<Body>) -> BeforeResult {
        todo!()
    }

    async fn after(&self, response: Response<Body>, request_data: RequestData) -> Response<Body> {
        todo!()
    }

    async fn success(&self, response: Response<Body>, request_data: RequestData) -> Response<Body> {
        todo!()
    }

    async fn failure(&self, response: Response<Body>, request_data: RequestData) -> Response<Body> {
        todo!()
    }

    async fn error(&self) -> Response<Body> {
        todo!()
    }

    async fn before_product_os_response(&self, request: Request<Body>) -> BeforeResult {
        todo!()
    }

    async fn after_product_os_response(&self, response: ProductOSResponse<Body>, request_data: RequestData) -> Response<Body> {
        todo!()
    }
}