insecure_reverse_proxy/
lib.rs1mod 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<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 Ok(res)
96 })
97 }
98}