Closed quinn closed 1 year ago
The line following the comment does exactly this :)
@imbolc thanks. Not sure why it didn't work for me :(
Hmm... I've just added an example which works for me locally, would you try to run it? What OS do you use?
Example works for me as well (i'm on ubuntu) I'm going to try to repro again
example you added works, however when I try to integrate it with hyper_reverse_proxy I get this error:
use axum::{
body::Body, extract::ConnectInfo, http::StatusCode, response::Response, routing::any, Router,
};
use axum_client_ip::ClientIp;
use hyper::Request;
use std::net::IpAddr;
use std::{convert::Infallible, net::SocketAddr};
fn debug_request(req: Request<Body>) -> Result<Response<Body>, Infallible> {
let body_str = format!("hi {:?}", req);
Ok(Response::new(Body::from(body_str)))
}
async fn handle(client_ip: IpAddr, req: Request<Body>) -> Result<Response<Body>, Infallible> {
if req.uri().path().starts_with("/target/first") {
// will forward requests to port 13901
match hyper_reverse_proxy::call(client_ip, "http://127.0.0.1:13901", req).await {
Ok(response) => Ok(response),
Err(_error) => Ok(Response::builder()
.status(StatusCode::INTERNAL_SERVER_ERROR)
.body(Body::empty())
.unwrap()),
}
} else if req.uri().path().starts_with("/target/second") {
// will forward requests to port 13902
match hyper_reverse_proxy::call(client_ip, "http://127.0.0.1:13902", req).await {
Ok(response) => Ok(response),
Err(_error) => Ok(Response::builder()
.status(StatusCode::INTERNAL_SERVER_ERROR)
.body(Body::empty())
.unwrap()),
}
} else {
debug_request(req)
}
}
#[tokio::main]
async fn main() {
let bind_string = "127.0.0.1:8000";
let bind_addr: SocketAddr = bind_string.parse().expect("Could not parse ip:port.");
async fn hello(
req: Request<Body>,
ClientIp(ip): ClientIp,
) -> Result<Response<Body>, Infallible> {
handle(ip, req).await
}
let app = Router::new().route("/", any(hello));
let server = axum::Server::bind(&bind_addr)
.serve(app.into_make_service_with_connect_info::<SocketAddr>());
println!("Running server on {:?}", bind_addr);
if let Err(e) = server.await {
eprintln!("server error: {}", e);
}
}
This is just the example code from their README added onto your example.
Try swapping these lines :)
req: Request<Body>,
ClientIp(ip): ClientIp,
Here's what's probably happening: https://docs.rs/axum/0.5.17/axum/extract/index.html#be-careful-when-extracting-request
In Axum v0.6 (which is released yesterday) it should be a compilation error:
The request body is an asynchronous stream that can only be consumed once. Therefore you can only have one extractor that consumes the request body. axum enforces by that requiring such extractors to be the last argument your handler takes.
https://docs.rs/axum/latest/axum/extract/index.html#the-order-of-extractors
in the docs I see:
Since I am running locally I'm not behind a proxy, and I get a message "Can't determine the client IP, check forwarding configuration". How do I add ConnectInfo?