awesome_operates/
proxy.rs

1// use std::time::Duration;
2//
3// use async_trait::async_trait;
4// use axum::body::Body;
5// use axum::extract::Request;
6// use axum::http;
7// use axum::response::{IntoResponse, Response};
8// use http::uri::{Parts, Scheme};
9// use http::Uri;
10// use snafu::ResultExt;
11// use tower::make::Shared;
12//
13// use crate::error::{RequestBodyReadSnafu, RequestProxySnafu, Result, UriFromPartsSnafu};
14//
15// #[async_trait]
16// pub trait HttpProxy: 'static {
17//     fn listen_addr() -> &'static str;
18//
19//     fn target_addr() -> String;
20//
21//     fn proxy_timeout() -> u64 {
22//         10
23//     }
24//
25//     fn default_schema() -> Scheme {
26//         Scheme::HTTP
27//     }
28//
29//     async fn service_proxy(req: Request<hyper::body::Incoming>) -> Result<Response> {
30//         let uri = req.uri();
31//
32//         let mut parts = Parts::default();
33//         parts.scheme = Some(Self::default_schema());
34//         parts.authority = Some(Self::target_addr().parse().unwrap());
35//         parts.path_and_query = uri.path_and_query().cloned();
36//         tracing::debug!("receive proxy: {parts:?} headers: {:?}", req.headers());
37//         let changed_uri = Uri::from_parts(parts).context(UriFromPartsSnafu)?;
38//
39//         let client = reqwest::Client::new();
40//         let resp = client
41//             .request(req.method().clone(), changed_uri.to_string())
42//             .headers(req.headers().clone())
43//             .body(req.into_body())
44//             .timeout(Duration::from_secs(Self::proxy_timeout()))
45//             .send()
46//             .await
47//             .context(RequestProxySnafu)?;
48//
49//         let status_code = resp.status();
50//         let headers = resp.headers().clone();
51//         tracing::debug!("proxy result {changed_uri:?} with resp: {status_code} {headers:?}");
52//         let body = resp.bytes().await.context(RequestBodyReadSnafu)?;
53//         let mut res = Body::from(body).into_response();
54//         *res.status_mut() = status_code;
55//         *res.headers_mut() = headers;
56//         Ok(res)
57//     }
58//
59//     async fn proxy_server() {
60//         tracing::info!("listening on {}", Self::listen_addr());
61//         let service = tower::service_fn(Self::service_proxy);
62//         hyper::Server::bind(&Self::listen_addr().parse().unwrap())
63//             .http1_preserve_header_case(true)
64//             .http1_title_case_headers(true)
65//             .serve(Shared::new(service))
66//             .await
67//             .unwrap();
68//     }
69// }