1use std::sync::Arc;
2
3use http_body_util::{BodyExt, Full};
4use hyper::{
5 Request, Response, StatusCode,
6 body::{Bytes, Incoming},
7};
8use log::{debug, error};
9use proxy_fetch::Fetch;
10
11pub async fn proxy(
12 url: String,
13 mut req: Request<Incoming>,
14 fetch: Arc<Fetch>,
15) -> std::result::Result<Response<Full<Bytes>>, hyper::Error> {
16 let method = req.method().clone();
17 let mut headers = req.headers().clone();
18
19 for i in ["proxy-authorization", "proxy-connection"] {
20 headers.remove(i);
21 }
22
23 let body = match req.body_mut().collect().await {
24 Ok(body) => body.to_bytes(),
25 Err(e) => {
26 error!("Failed to collect request body: {}", e);
27 let response = Response::builder()
28 .status(StatusCode::BAD_REQUEST)
29 .body(Full::new(Bytes::from("Bad Request")))
30 .unwrap();
31 return Ok(response);
32 }
33 };
34
35 debug!("{url} {:?}", headers);
36 match fetch.run(method, url, headers, Some(body)).await {
37 Ok(res) => {
38 let mut builder = Response::builder().status(res.status);
39 for (key, value) in res.headers {
40 if let Some(key) = key {
41 builder = builder.header(key, value);
42 }
43 }
44 Ok(builder.body(Full::new(res.body)).unwrap())
45 }
46 Err(e) => {
47 error!("Fetch error: {}", e);
48 Ok(
49 Response::builder()
50 .status(StatusCode::INTERNAL_SERVER_ERROR)
51 .body(Full::new(Bytes::from("Internal Server Error")))
52 .unwrap(),
53 )
54 }
55 }
56}