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