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
8pub trait RequestHandler: Send + Sync {
10 fn handle_request(&self, req: &mut Request<BoxBody>);
13
14 fn handle_response(&self, res: &mut Response<BoxBody>);
17}
18
19pub 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
38pub 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}
45
46pub fn full_boxed_body(bytes: Bytes) -> BoxBody {
48 http_body_util::Full::new(bytes)
49 .map_err(|never| match never {})
50 .boxed()
51}
52
53pub fn extract_body_bytes(req: &mut Request<BoxBody>) -> Bytes {
55 let body = std::mem::replace(req.body_mut(), empty_boxed_body());
56 futures_util::FutureExt::now_or_never(async {
60 body.collect().await.map(|c| c.to_bytes()).unwrap_or_default()
61 })
62 .unwrap_or_default()
63}
64
65pub fn extract_response_body_bytes(res: &mut Response<BoxBody>) -> Bytes {
67 let body = std::mem::replace(res.body_mut(), empty_boxed_body());
68 futures_util::FutureExt::now_or_never(async {
69 body.collect().await.map(|c| c.to_bytes()).unwrap_or_default()
70 })
71 .unwrap_or_default()
72}
73
74pub fn put_body_back(req: &mut Request<BoxBody>, bytes: Bytes) {
76 *req.body_mut() = full_boxed_body(bytes);
77}
78
79pub fn put_response_body_back(res: &mut Response<BoxBody>, bytes: Bytes) {
81 *res.body_mut() = full_boxed_body(bytes);
82}
83
84pub fn empty_boxed_body() -> BoxBody {
86 http_body_util::Empty::new()
87 .map_err(|never| match never {})
88 .boxed()
89}
90
91#[derive(Clone)]
93pub struct Dropped;
94
95#[derive(Clone)]
97pub struct Buffered;