I'm quite new to rust, I only started a few days ago.
I'm trying to create a gateway with ssl, basically mashing up
this example
and
this example
Clip of the source:
let service = make_service_fn(
move |s: &tokio_rustls::server::TlsStream<tokio::net::TcpStream>| {
let client = client.clone();
let (tls_stream, server_session) = s.get_ref();
async move {
Ok::<_, io::Error>(service_fn(move |req: Request<Body>| {
proxy(req, client.to_owned(), tls_stream.peer_addr().unwrap())
}))
}
},
);
async fn proxy(
req: Request<Body>,
client: hyper::Client<hyper_rustls::HttpsConnector<hyper::client::HttpConnector>>,
ip: std::net::SocketAddr,
) -> Result<Response<Body>, GenericError> {
// Prepare the HTTPS connector.
let out_addr = "https://cloudflare.com";
let uri_string = format!(
"{}{}",
out_addr,
req
.uri()
.path_and_query()
.map(|x| x.as_str())
.unwrap_or("/")
)
.to_owned();
let (mut parts, body) = req.into_parts();
parts.headers.remove("Host");
// this is the part that I want to implement.
// parts.headers.append(
// "x-forwarded-for",
// HeaderValue::from_str(&format!("{}", remote_addr)).unwrap(),
//);
let mut request: Request<Body> = Request::from_parts(parts, body);
*request.uri_mut() = uri_string.parse().unwrap();
let forward_res = client.request(request);
Ok(forward_res.await.unwrap())
}
I'm trying to add the x-forwarded-for header, so I need to get the client's ip address. Hyper's AddrStream
docs.rs/hyper/0.14.9/hyper/server/conn/struct.AddrStream.html#impl( Can't put two links because I'm a new user)
has a remote_addr function to get the remote ip address,
However, hyper-rustls uses a custom acceptor for the incoming tcp stream, which doesn't implement the remote_addr function.
I researched on the topic, and found that I could get the client ip from the underlying tcp stream:
let (tls_stream, server_session) = s.get_ref();
let client_ip = tls_stream.peer_addr().unwrap()
However, I'm getting errors about the compiler not being able to infer an appropropriate lifetime. I couldn't find a solution that worked anywhere.
The error:
error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
--> src/main.rs:75:44
|
75 | let (tls_stream, server_session) = s.get_ref();
| ^^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the body at 73:5...
--> src/main.rs:73:5
|
73 | / move |s: &tokio_rustls::server::TlsStream<tokio::net::TcpStream>| {
74 | | let client = client.clone();
75 | | let (tls_stream, server_session) = s.get_ref();
76 | | async move {
... |
80 | | }
81 | | },
| |_____^
note: ...so that reference does not outlive borrowed content
--> src/main.rs:75:42
|
75 | let (tls_stream, server_session) = s.get_ref();
| ^
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that the type `hyper::server::conn::spawn_all::NewSvcTask<tokio_rustls::server::TlsStream<tokio::net::TcpStream>, impl futures_util::Future, hyper::service::util::ServiceFn<[closure@src/main.rs:77:39: 79:10], Body>, hyper::common::exec::Exec, hyper::server::conn::spawn_all::NoopWatcher>` will meet its required lifetime bounds
--> src/main.rs:87:4
|
87 | .serve(service);
| ^^^^^
error: aborting due to previous error; 1 warning emitted
For more information about this error, try `rustc --explain E0495`.
error: could not compile `hyper-proxy
Thanks in advance!