1use std::sync::Arc;
2
3use axum::{body::Body, extract::Request, response::Response};
4use ic_bn_lib_common::{
5 traits::http::{Client, ClientHttp},
6 types::http::Error,
7};
8use url::Url;
9
10use super::{body::SyncBody, headers::strip_connection_headers};
11
12pub async fn proxy(
14 url: Url,
15 request: Request,
16 http_client: &Arc<dyn Client>,
17) -> Result<Response, Error> {
18 let (mut parts, body) = request.into_parts();
20
21 strip_connection_headers(&mut parts.headers);
23
24 let mut request = reqwest::Request::new(parts.method.clone(), url);
25 *request.headers_mut() = parts.headers;
26
27 *request.body_mut() = Some(reqwest::Body::wrap(SyncBody::new(body)));
29
30 let response = http_client.execute(request).await?;
32
33 let response: http::Response<_> = response.into();
35 let (parts, body) = response.into_parts();
36
37 Ok(Response::from_parts(parts, Body::new(body)))
38}
39
40pub async fn proxy_http<B>(
42 mut request: Request<B>,
43 http_client: &Arc<dyn ClientHttp<B>>,
44) -> Result<Response, Error> {
45 strip_connection_headers(request.headers_mut());
47
48 let response = http_client.execute(request).await?;
50
51 let (parts, body) = response.into_parts();
53 Ok(Response::from_parts(parts, Body::new(body)))
54}
55
56#[cfg(test)]
57mod test {
58 use std::sync::Arc;
59
60 use axum::{body::Body, extract::Request};
61 use http_body::Body as _;
62 use ic_bn_lib_common::traits::http::Client;
63
64 use crate::http::proxy::proxy;
65
66 #[derive(Debug)]
67 struct HttpClient;
68
69 #[async_trait::async_trait]
70 impl Client for HttpClient {
71 async fn execute(&self, _: reqwest::Request) -> Result<reqwest::Response, reqwest::Error> {
72 Ok(reqwest::Response::from(
73 http::response::Builder::new()
74 .status(200)
75 .body(reqwest::Body::from("foobarbaz"))
76 .unwrap(),
77 ))
78 }
79 }
80
81 #[tokio::test]
82 async fn test_size_hint() {
83 let cli = Arc::new(HttpClient) as Arc<dyn Client>;
84 let url = url::Url::parse("http://foo.bar").unwrap();
85 let request = Request::new(Body::empty());
86 let resp = proxy(url, request, &cli).await.unwrap();
87
88 assert_eq!(resp.body().size_hint().exact(), Some(9));
89 }
90}