proxy_http/
proxy.rs

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}