1
0
mirror of https://github.com/actix/examples synced 2025-02-23 17:53:02 +01:00

107 lines
3.3 KiB
Rust
Raw Normal View History

2019-03-26 23:33:13 -07:00
use actix_web::client::Client;
use actix_web::{middleware, web, App, Error, HttpRequest, HttpResponse, HttpServer};
use clap::{value_t, Arg};
2019-03-26 23:33:13 -07:00
use futures::Future;
use std::net::ToSocketAddrs;
use url::Url;
fn forward(
2019-03-26 23:33:13 -07:00
req: HttpRequest,
payload: web::Payload,
url: web::Data<Url>,
client: web::Data<Client>,
) -> impl Future<Item = HttpResponse, Error = Error> {
let mut new_url = url.get_ref().clone();
new_url.set_path(req.uri().path());
new_url.set_query(req.uri().query());
2019-04-12 13:39:14 -07:00
let forwarded_req = client.request_from(new_url.as_str(), req.head());
2019-03-26 23:33:13 -07:00
// if let Some(addr) = req.peer_addr() {
// match forwarded_req.headers_mut().entry("x-forwarded-for") {
// Ok(http::header::Entry::Vacant(entry)) => {
// let addr = format!("{}", addr.ip());
// entry.insert(addr.parse().unwrap());
// }
// Ok(http::header::Entry::Occupied(mut entry)) => {
// let addr = format!("{}, {}", entry.get().to_str().unwrap(), addr.ip());
// entry.insert(addr.parse().unwrap());
// }
// _ => unreachable!(),
// }
// }
forwarded_req
2019-03-26 23:33:13 -07:00
.send_stream(payload)
.map_err(Error::from)
2019-03-26 23:33:13 -07:00
.map(|res| {
let mut client_resp = HttpResponse::build(res.status());
for (header_name, header_value) in
res.headers().iter().filter(|(h, _)| *h != "connection")
{
client_resp.header(header_name.clone(), header_value.clone());
}
client_resp.streaming(res)
})
}
2019-03-26 23:33:13 -07:00
fn main() -> std::io::Result<()> {
let matches = clap::App::new("HTTP Proxy")
.arg(
Arg::with_name("listen_addr")
.takes_value(true)
.value_name("LISTEN ADDR")
.index(1)
.required(true),
2019-03-09 18:03:09 -08:00
)
.arg(
Arg::with_name("listen_port")
.takes_value(true)
.value_name("LISTEN PORT")
.index(2)
.required(true),
2019-03-09 18:03:09 -08:00
)
.arg(
Arg::with_name("forward_addr")
.takes_value(true)
.value_name("FWD ADDR")
.index(3)
.required(true),
2019-03-09 18:03:09 -08:00
)
.arg(
Arg::with_name("forward_port")
.takes_value(true)
.value_name("FWD PORT")
.index(4)
.required(true),
2019-03-09 18:03:09 -08:00
)
.get_matches();
let listen_addr = matches.value_of("listen_addr").unwrap();
let listen_port = value_t!(matches, "listen_port", u16).unwrap_or_else(|e| e.exit());
let forwarded_addr = matches.value_of("forward_addr").unwrap();
let forwarded_port =
value_t!(matches, "forward_port", u16).unwrap_or_else(|e| e.exit());
let forward_url = Url::parse(&format!(
"http://{}",
(forwarded_addr, forwarded_port)
.to_socket_addrs()
.unwrap()
.next()
.unwrap()
2019-03-09 18:03:09 -08:00
))
.unwrap();
2019-03-26 23:33:13 -07:00
HttpServer::new(move || {
App::new()
.data(forward_url.clone())
.wrap(middleware::Logger::default())
.default_resource(|r| r.to_async(forward))
2019-03-09 18:03:09 -08:00
})
2019-03-26 23:33:13 -07:00
.bind((listen_addr, listen_port))?
.system_exit()
2019-03-26 23:33:13 -07:00
.run()
}