Skip to main content

rustgate/
handler.rs

1use bytes::Bytes;
2use http_body_util::BodyExt;
3use hyper::{Request, Response};
4use tracing::info;
5
6pub type BoxBody = http_body_util::combinators::BoxBody<Bytes, hyper::Error>;
7
8/// Trait for intercepting and modifying HTTP requests and responses.
9pub trait RequestHandler: Send + Sync {
10    /// Called before forwarding the request to upstream.
11    /// Modify the request in place to alter what gets sent.
12    fn handle_request(&self, req: &mut Request<BoxBody>);
13
14    /// Called before sending the response back to the client.
15    /// Modify the response in place to alter what the client receives.
16    fn handle_response(&self, res: &mut Response<BoxBody>);
17}
18
19/// Default handler that logs requests and responses without modification.
20pub struct LoggingHandler;
21
22impl RequestHandler for LoggingHandler {
23    fn handle_request(&self, req: &mut Request<BoxBody>) {
24        let path = req.uri().path();
25        let display_uri = if req.uri().query().is_some() {
26            format!("{path}?<redacted>")
27        } else {
28            path.to_string()
29        };
30        info!(">> {} {} {:?}", req.method(), display_uri, req.version());
31    }
32
33    fn handle_response(&self, res: &mut Response<BoxBody>) {
34        info!("<< {}", res.status());
35    }
36}
37
38/// Convert an incoming body to our BoxBody type.
39pub fn boxed_body<B>(body: B) -> BoxBody
40where
41    B: hyper::body::Body<Data = Bytes, Error = hyper::Error> + Send + Sync + 'static,
42{
43    body.boxed()
44}