
什么是 ntex?
Ntex是一个功能强大、实用且速度极快的 Rust 可组合网络服务框架。
它是 Rust 中最快的 Web 框架之一,为 Web 服务器开发提供了强大的抽象。
为什么选择 ntex?
以下是我使用 ntex 的主要原因:
性能:Ntex 是 Rust 中最快的 Web 框架之一。
符合人体工程学:Ntex 为 Web 服务器开发提供了强大的抽象。
可组合:Ntex 设计为可组合,允许您使用简单的组件构建复杂的 Web 服务器。
生态系统:Ntex 拥有丰富的中间件、扩展和库生态系统。
内置 http 客户端:Ntex 提供内置的 http 客户端,用于向其他服务器发出请求。
运行时:Ntex 允许您在不同的运行时之间进行选择,包括 tokio 和 async-std。
设置项目
让我们首先用 Cargo 创建一个新项目:
cargo new ntex-http-proxycd ntex-http-proxy
添加 ntex 作为依赖项:
cargo add ntex --features tokio
从基本的 http 处理程序开始
让我们首先创建一个Hello, World!以纯文本格式返回的基本 http 处理程序:
use ntex::{http, web};async fn forward() -> Result<web::HttpResponse, web::Error> {Ok(web::HttpResponse::Ok().content_type("text/plain").body("Hello, world!"),)}#[ntex::main]async fn main() -> std::io::Result<()> {web::server(move || {web::App::new().state(http::Client::new()).wrap(web::middleware::Logger::default()).default_service(web::route().to(forward))}).bind(("0.0.0.0", 9090))?.stop_runtime().run().await}
让我们分解一下代码:
forwardweb::HttpResponse是一个返回 a或 a 的异步函数web::Error。main是我们应用程序的入口点。它是一个返回 的异步函数std::io::Result<()>。我们创建一个新的 ntex 网络服务器
web::server并传递一个返回的闭包web::App。我们创建一个新的
http::Client并将其添加到应用程序状态。我们向应用程序添加了一个记录器中间件。
我们定义一个默认服务,将所有请求转发给
forward处理程序。我们绑定服务器
0.0.0.0:9090并运行它。
让我们运行该服务器来测试它:
cargo runcurl http://localhost:9090
您应该Hello, world!在回应中看到。
添加代理处理程序
我们首先将url和futures_util板条箱添加到我们的依赖项中,以便能够解析 URL 并将响应转换为流:
cargo add url futures-util
然后我们更改代码以将请求转发到另一台服务器:
use futures_util::TryStreamExt;use ntex::{http, web};async fn forward(req: web::HttpRequest,body: ntex::util::Bytes,client: web::types::State<http::Client>,forward_url: web::types::State<url::Url>,) -> Result<web::HttpResponse, web::Error> {let mut new_url = forward_url.get_ref().clone();new_url.set_path(req.uri().path());new_url.set_query(req.uri().query());let forwarded_req = client.request_from(new_url.as_str(), req.head());let res = forwarded_req.send_body(body).await.map_err(web::Error::from)?;let mut client_resp = web::HttpResponse::build(res.status());let stream = res.into_stream();Ok(client_resp.streaming(stream))}#[ntex::main]async fn main() -> std::io::Result<()> {let forward_url = "https://www.rust-lang.org".to_owned();let forward_url = url::Url::parse(&forward_url).map_err(|err| std::io::Error::new(std::io::ErrorKind::InvalidData, err))?;web::server(move || {web::App::new().state(http::Client::new()).state(forward_url.clone()).wrap(web::middleware::Logger::default()).default_service(web::route().to(forward))}).bind(("0.0.0.0", 9090))?.run().await}
让我们分解一下代码:
我们将
url和futures_util板条箱添加到我们的依赖项中。我们改变
forward函数以将请求、主体、客户端和 forward_url 作为参数。我们通过克隆forward_url并从请求中设置路径和查询来创建一个新的url。
我们使用客户端和新的 URL 创建一个新请求。
我们发送请求的主体并等待响应。
我们用响应的状态代码构建一个新的响应。
我们将响应转换为流并返回它。
让我们运行该服务器来测试它:
cargo runcurl http://localhost:9090
您应该在响应中看到 rust-lang.org 主页。
结论
在本教程中,我们使用 ntex 创建了一个基本的 http 代理服务器。我们首先创建一个Hello, World!以纯文本格式返回的简单 http 处理程序。然后,我们添加了一个将请求转发到另一台服务器的代理处理程序。我们使用url和futures_utilcrate 来解析 URL 并将响应转换为流。我们通过运行服务器并向其发出请求来测试服务器。我们看到服务器成功将请求转发到目标服务器并返回响应。
我们几乎没有代码来编写一个基本的 http 代理服务器(不到 50 行代码),我们可以轻松地使用更多功能(如缓存、速率限制、身份验证等)对其进行扩展。

