Files
rrpsfd/src/server/reqwest_proxy.rs
2025-10-31 06:51:23 +03:00

61 lines
1.6 KiB
Rust

use std::{str::FromStr, sync::Arc};
use bytes::Bytes;
use reqwest::{
Method,
header::{HeaderMap, HeaderName, HeaderValue},
redirect::Policy,
};
use crate::settings::Result;
use super::{Connection, HttpRequest, HttpResponse, ServerProxyService};
pub struct ReqwestProxy {
client: reqwest::Client,
}
#[async_trait::async_trait]
impl ServerProxyService for ReqwestProxy {
async fn new() -> Arc<Self> {
Self {
client: reqwest::ClientBuilder::new()
.redirect(Policy::none())
.build()
.expect("Can't build client"),
}
.into()
}
async fn fetch(&self, req: HttpRequest, connection: Connection) -> Result<HttpResponse> {
let mut headers = HeaderMap::new();
for (key, value) in req.headers {
headers.append(key.parse::<HeaderName>()?, value.parse::<HeaderValue>()?);
}
let res = self
.client
.request(
Method::from_str(&req.method)?,
format!(
"{}://{}:{}{}",
connection.protocol, connection.ip_address, connection.port, req.path
),
)
.headers(headers)
.body(req.body)
.send()
.await?;
let headers = res
.headers()
.iter()
.map(|(k, v)| (k.to_string(), v.to_str().unwrap_or("").to_string()))
.collect();
Ok(HttpResponse::new(
res.status().as_u16(),
headers,
res.bytes().await.ok().unwrap_or_else(|| Bytes::new()),
))
}
}