8 个版本 (4 个重大更新)
0.5.1 | 2022 年 3 月 12 日 |
---|---|
0.5.0 | 2022 年 3 月 12 日 |
0.4.0 | 2019 年 3 月 11 日 |
0.3.0 | 2019 年 2 月 16 日 |
0.1.1 | 2017 年 7 月 15 日 |
#1928 in 网络编程
每月 567 次下载
在 9 个库中使用了 9 (直接使用 7 个)
10KB
99 行
hyper-reverse-proxy
一个简单的反向代理,用于与 Hyper 一起使用。
实现确保在两个方向上正确删除 跳到跳头,并将客户端 IP 地址添加到 X-Forwarded-For
头中的逗号分隔的转发地址列表中。
该实现基于 Go 的 httputil.ReverseProxy
。
示例
将以下依赖项添加到您的 Cargo.toml
文件中。
[dependencies]
hyper-reverse-proxy = "0.5"
hyper = { version = "0.14", features = ["full"] }
tokio = { version = "1", features = ["full"] }
以下示例将设置一个监听在 127.0.0.:13900
的反向代理,并将代理以下调用
-
"/target/first"
将被代理到http://127.0.0.1:13901
-
"/target/second"
将被代理到http://127.0.0.1:13902
-
所有其他 URL 将由
debug_request
函数处理,该函数将显示请求信息。
use hyper::server::conn::AddrStream;
use hyper::{Body, Request, Response, Server, StatusCode};
use hyper::service::{service_fn, make_service_fn};
use std::{convert::Infallible, net::SocketAddr};
use std::net::IpAddr;
fn debug_request(req: Request<Body>) -> Result<Response<Body>, Infallible> {
let body_str = format!("{:?}", 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_addr = "127.0.0.1:8000";
let addr:SocketAddr = bind_addr.parse().expect("Could not parse ip:port.");
let make_svc = make_service_fn(|conn: &AddrStream| {
let remote_addr = conn.remote_addr().ip();
async move {
Ok::<_, Infallible>(service_fn(move |req| handle(remote_addr, req)))
}
});
let server = Server::bind(&addr).serve(make_svc);
println!("Running server on {:?}", addr);
if let Err(e) = server.await {
eprintln!("server error: {}", e);
}
}
依赖项
~4–5.5MB
~94K SLoC