actix-proxy

Crates.ioactix-proxy
lib.rsactix-proxy
version0.2.0
sourcesrc
created_at2021-04-10 13:05:26.478044
updated_at2023-02-09 14:56:35.851953
descriptionGlue code for using awc with actix-web
homepage
repositoryhttps://github.com/jofas/actix_proxy
max_upload_size
id381682
size12,155
Jonas Fassbender (jofas)

documentation

README

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()
}
Commit count: 42

cargo fmt