5个版本

0.2.1 2023年9月11日
0.2.0 2023年4月26日
0.1.2 2023年3月7日
0.1.1 2022年12月27日
0.1.0 2022年12月27日

HTTP服务器中排名第896

每月下载量:36次

MIT/Apache

51KB
1K SLoC

reverse-proxy-service 是 tower 的 Service,执行反向代理。

这些 Service 是为了在 axum 中使用而实现的,但它们可以用于更通用的情况。

请参阅文档


lib.rs:

reverse-proxy-service 是执行“反向代理”的 tower Service,具有各种重写规则。

内部这些服务使用 hyper::Client 将传入请求发送到另一个服务器。客户端的连接器可以是 HttpConnectorHttpsConnector 或任何你想要的。

示例

有两种类型的服务,OneshotServiceReusedServiceOneshotService 拥有 Client,而 ReusedService 通过 Arc 共享 Client

通用用法

use reverse_proxy_service::ReusedServiceBuilder;
use reverse_proxy_service::{ReplaceAll, ReplaceN};

use hyper::body::Body;
use http::Request;
use tower_service::Service as _;

let svc_builder = reverse_proxy_service::builder_http("example.com:1234").unwrap();

let req1 = Request::builder()
    .method("GET")
    .uri("https://myserver.com/foo/bar/foo")
    .body(Body::empty())
    .unwrap();

// Clones Arc<Client>
let mut svc1 = svc_builder.build(ReplaceAll("foo", "baz"));
// http://example.com:1234/baz/bar/baz
let _res = svc1.call(req1).await.unwrap();

let req2 = Request::builder()
    .method("POST")
    .uri("https://myserver.com/foo/bar/foo")
    .header("Content-Type", "application/x-www-form-urlencoded")
    .body(Body::from("key=value"))
    .unwrap();

let mut svc2 = svc_builder.build(ReplaceN("foo", "baz", 1));
// http://example.com:1234/baz/bar/foo
let _res = svc2.call(req2).await.unwrap();

在这个示例中,svc1svc2共享同一个Client,它们内部持有Arc<Client>

有关重写规则(如ReplaceAllReplaceN等)的更多信息,请参阅rewrite的文档。

使用axum

use reverse_proxy_service::ReusedServiceBuilder;
use reverse_proxy_service::{TrimPrefix, AppendSuffix, Static};

use axum::Router;

#[tokio::main]
async fn main() {
    let host1 = reverse_proxy_service::builder_http("example.com").unwrap();
    let host2 = reverse_proxy_service::builder_http("example.net:1234").unwrap();

    let app = Router::new()
        .route_service("/healthcheck", host1.build(Static("/")))
        .route_service("/users/*path", host1.build(TrimPrefix("/users")))
        .route_service("/posts", host2.build(AppendSuffix("/")));

    axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
        .serve(app.into_make_service())
        .await
        .unwrap();
}

返回类型

ReusedServiceOneshotService的返回类型是Result<Result<Response, Error>, Infallible>。这是因为axum的Router只接受此类Service

如果启用axum特性,Error类型实现了IntoResponse。它返回一个空体,状态码为INTERNAL_SERVER_ERROR。此错误的描述将在error级别在into_response()方法中记录。

特性

默认情况下,仅启用http1

  • http1:使用hyper/http1
  • http2:使用hyper/http2
  • https:别名nativetls
  • nativetls:使用hyper-tls存储库
  • rustls:别名rustls-webpki-roots
  • rustls-webpki-roots:使用hyper-rustls存储库,带有webpki-roots特性
  • rustls-native-roots:使用hyper-rustls存储库,带有rustls-native-certs特性
  • rustls-http2http2rustls,并启用rustls/http2
  • axum:为Error实现IntoResponse

您必须启用http1http2之一。如果您仅启用了https特性,则无法使用服务。

通过此文档,我们使用rustls来表示任何 rustls*特性,除非有其他说明。

依赖关系

~7–20MB
~284K SLoC