insecure_reverse_proxy/
lib.rs

1mod hyper_reverse_proxy;
2
3use std::{
4    task::{Context, Poll},
5    time::Duration,
6};
7
8use futures_util::future::BoxFuture;
9use http::{Request, Response};
10use http_body::Body as HttpBody;
11use hyper::body::Incoming;
12use hyper_reverse_proxy::HyperReverseProxy;
13use hyper_util::{
14    client::legacy::{
15        connect::{Connect, HttpConnector},
16        Client,
17    },
18    rt::TokioExecutor,
19};
20use tower::Service;
21
22pub struct InsecureReverseProxyService<C, Body> {
23    pub target: String,
24    pub proxy: HyperReverseProxy<C, Body>,
25}
26
27pub type HttpReverseProxyService<Body> = InsecureReverseProxyService<HttpConnector, Body>;
28
29impl<C, B> InsecureReverseProxyService<C, B> {
30    pub fn new(
31        target: impl Into<String>,
32        client: Client<C, B>,
33    ) -> InsecureReverseProxyService<C, B> {
34        Self {
35            target: target.into(),
36            proxy: HyperReverseProxy::new(client),
37        }
38    }
39}
40
41impl<B> InsecureReverseProxyService<HttpConnector, B> {
42    pub fn new_http(target: impl Into<String>) -> InsecureReverseProxyService<HttpConnector, B>
43    where
44        B: HttpBody + Send,
45        B::Data: Send,
46    {
47        Self {
48            target: target.into(),
49            proxy: HyperReverseProxy::new(
50                Client::builder(TokioExecutor::new())
51                    .pool_idle_timeout(Duration::from_secs(30))
52                    .build_http(),
53            ),
54        }
55    }
56}
57
58impl<C: Clone, B> Clone for InsecureReverseProxyService<C, B> {
59    #[inline]
60    fn clone(&self) -> Self {
61        Self {
62            target: self.target.clone(),
63            proxy: self.proxy.clone(),
64        }
65    }
66}
67
68impl<C, Body> Service<Request<Body>> for InsecureReverseProxyService<C, Body>
69where
70    C: Connect + Clone + Send + Sync + 'static,
71    Body: HttpBody + Send + 'static + Unpin,
72    Body::Data: Send,
73    Body::Error: Into<Box<dyn std::error::Error + Send + Sync>>,
74{
75    // type Response = Response<UnsyncBoxBody<Bytes, HyperError>>;
76    type Response = Response<Incoming>;
77    type Error = std::convert::Infallible;
78    type Future = BoxFuture<'static, Result<Self::Response, Self::Error>>;
79
80    fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
81        Poll::Ready(Ok(()))
82    }
83
84    fn call(&mut self, request: Request<Body>) -> Self::Future {
85        let target = self.target.clone();
86        let proxy = self.proxy.clone();
87
88        Box::pin(async move {
89            let res = proxy
90                .call("127.0.0.1".parse().unwrap(), target.clone(), request)
91                .await
92                .unwrap();
93            // .map(|body| body.boxed_unsync());
94
95            Ok(res)
96        })
97    }
98}