2 unstable releases

0.2.0 Feb 9, 2023
0.1.0 Apr 10, 2021

#465 in HTTP server

Download history 80/week @ 2024-03-11 63/week @ 2024-03-18 137/week @ 2024-03-25 212/week @ 2024-04-01 160/week @ 2024-04-08 147/week @ 2024-04-15 162/week @ 2024-04-22 113/week @ 2024-04-29 152/week @ 2024-05-06 201/week @ 2024-05-13 319/week @ 2024-05-20 202/week @ 2024-05-27 198/week @ 2024-06-03 200/week @ 2024-06-10 151/week @ 2024-06-17 96/week @ 2024-06-24

654 downloads per month
Used in zero4rs

MIT license

9KB
51 lines

actix-proxy

Build Status Codecov Latest Version Downloads Docs License: MIT

A rust library for the actix-web framework. Glues together the actix-web and awc crates.

This library provides the IntoHttpResponse trait which transforms a awc::ClientResponse into a actix_web::HttpResponse and the SendRequestError type bridging the gap between awc's SendRequestError and actix-web, by implementing actix_web::ResponseError.

Sometimes you want to implement a gateway or proxy, which makes a request to some remote service and forwards the response to the client that made the request. actix-web integrates with the awc::Client HTTP client. Unfortunately, awc::ClientResponse, the response type of the client request, does not implement the Responder trait. Because of that, you can't return awc::ClientResponse from an endpoint of your actix-web server. This makes it hard to forward the response from the remote location through an endpoint of the proxy, requiring you to transform the response into a type that implements Responder.

With the IntoHttpResponse trait offered by actix-proxy, all you need to do is call the into_http_response method on your awc::ClientResponse to forward the response from the remote service through the proxy to the original caller.

Example

In this example we create a basic proxy for the duckduckgo search engine, simply forwarding the called url's path, query and fragment parts to duckduckgo:

use awc::Client;

use actix_web::{get, web, HttpResponse};

use actix_proxy::{IntoHttpResponse, SendRequestError};

#[get("/{url:.*}")]
async fn proxy(
  path: web::Path<(String,)>,
  client: web::Data<Client>,
) -> Result<HttpResponse, SendRequestError> {
  let (url,) = path.into_inner();

  let url = format!("https://duckduckgo.com/{url}");

  // here we use `IntoHttpResponse` to return the request to 
  // duckduckgo back to the client that called this endpoint
  Ok(client.get(&url).send().await?.into_http_response())
}

Alternatively, you can use the into_wrapped_http_response method to avoid having to wrap your result in an Ok(..) by hand:

use awc::Client;

use actix_web::{get, web, HttpResponse};

use actix_proxy::{IntoHttpResponse, SendRequestError};

#[get("/{url:.*}")]
async fn proxy(
  path: web::Path<(String,)>,
  client: web::Data<Client>,
) -> Result<HttpResponse, SendRequestError> {
  let (url,) = path.into_inner();

  let url = format!("https://duckduckgo.com/{url}");

  // here we use `IntoHttpResponse` to return the request to 
  // duckduckgo back to the client that called this endpoint
  client.get(&url).send().await?.into_wrapped_http_response()
}

Dependencies

~18–29MB
~532K SLoC