Basic http proxy in rust with ntex

What is ntex ?

Ntex is a powerful, pragmatic, and extremely fast framework for composable networking services for Rust.
It’s one of the fastest web frameworks available in Rust, and provides powerful abstractions for web server development.


This content originally appeared on DEV Community and was authored by leone

What is ntex ?

Ntex is a powerful, pragmatic, and extremely fast framework for composable networking services for Rust.
It's one of the fastest web frameworks available in Rust, and provides powerful abstractions for web server development.

Why ntex ?

This are my top reasons for using ntex:

  • Performance: Ntex is one of the fastest web frameworks available in Rust.
  • Ergonomic: Ntex provides powerful abstractions for web server development.
  • Composable: Ntex is designed to be composable, allowing you to build complex web servers from simple components.
  • Ecosystem: Ntex has a rich ecosystem of middleware, extensions and libraries.
  • Built-in http client: Ntex provides a built-in http client for making requests to other servers.
  • Runtime: Ntex allow you to choose between different runtimes, including tokio and async-std.

Setting up the project

Let's start by creating a new project with cargo:

cargo new ntex-http-proxy
cd ntex-http-proxy

Add ntex as dependency:

cargo add ntex --features tokio

Starting with a basic http handler

Let's start by creating a basic http handler that will return Hello, World! in plain text format:

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))?
  .run()
  .await
}

Let's break down the code:

  • forward is an async function that returns a web::HttpResponse or a web::Error.
  • main is the entry point of our application. It's an async function that returns a std::io::Result<()>.
  • We create a new ntex web server with web::server and pass a closure that returns a web::App.
  • We create a new http::Client and add it to the app state.
  • We add a logger middleware to the app.
  • We define a default service that will forward all requests to the forward handler.
  • We bind the server to 0.0.0.0:9090 and run it.

Let's test the server by running it:

cargo run
curl http://localhost:9090

You should see Hello, world! in the response.

Adding a proxy handler

We start by adding the url and futures_util crates to our dependencies to be able to parse urls and convert responses to streams:

cargo add url futures-util

Then we change the the code to forward requests to another server:

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
}

Let's break down the code:

  • We add the url and futures_util crates to our dependencies.
  • We change the forward function to take the request, body, client and forward_url as arguments.
  • We create a new url by cloning the forward_url and setting the path and query from the request.
  • We create a new request using the client and the new url.
  • We send the body of the request and await the response.
  • We build a new response with the status code of the response.
  • We convert the response into a stream and return it.

Let's test the server by running it:

cargo run
curl http://localhost:9090

You should see the rust-lang.org homepage in the response.

Conclusion

In this tutorial, we created a basic http proxy server using ntex. We started by creating a simple http handler that returns Hello, World! in plain text format. Then we added a proxy handler that forwards requests to another server. We used the url and futures_util crates to parse urls and convert responses to streams. We tested the server by running it and making a request to it. We saw that the server successfully forwarded the request to the target server and returned the response.
We have little to no code to write a basic http proxy server (less than 50 lines of code) and we can easily extend it with more features like caching, rate limiting, authentication, etc.

I hope you enjoyed this tutorial and found it useful. If you have any questions or feedback, feel free to leave a comment below.


This content originally appeared on DEV Community and was authored by leone


Print Share Comment Cite Upload Translate Updates
APA

leone | Sciencx (2025-09-05T17:21:45+00:00) Basic http proxy in rust with ntex. Retrieved from https://www.scien.cx/2025/09/05/basic-http-proxy-in-rust-with-ntex/

MLA
" » Basic http proxy in rust with ntex." leone | Sciencx - Friday September 5, 2025, https://www.scien.cx/2025/09/05/basic-http-proxy-in-rust-with-ntex/
HARVARD
leone | Sciencx Friday September 5, 2025 » Basic http proxy in rust with ntex., viewed ,<https://www.scien.cx/2025/09/05/basic-http-proxy-in-rust-with-ntex/>
VANCOUVER
leone | Sciencx - » Basic http proxy in rust with ntex. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2025/09/05/basic-http-proxy-in-rust-with-ntex/
CHICAGO
" » Basic http proxy in rust with ntex." leone | Sciencx - Accessed . https://www.scien.cx/2025/09/05/basic-http-proxy-in-rust-with-ntex/
IEEE
" » Basic http proxy in rust with ntex." leone | Sciencx [Online]. Available: https://www.scien.cx/2025/09/05/basic-http-proxy-in-rust-with-ntex/. [Accessed: ]
rf:citation
» Basic http proxy in rust with ntex | leone | Sciencx | https://www.scien.cx/2025/09/05/basic-http-proxy-in-rust-with-ntex/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.