proxy_http 0.1.9

Async HTTP proxy server in Rust. / Rust 异步 HTTP 代理服务器。
Documentation
use std::sync::Arc;

use http_body_util::{BodyExt, Full};
use hyper::{
  Request, Response, StatusCode,
  body::{Bytes, Incoming},
};
use log::{debug, error};
use proxy_fetch::Fetch;

pub async fn proxy(
  url: String,
  mut req: Request<Incoming>,
  fetch: Arc<Fetch>,
) -> std::result::Result<Response<Full<Bytes>>, hyper::Error> {
  let method = req.method().clone();
  let mut headers = req.headers().clone();

  for i in ["proxy-authorization", "proxy-connection"] {
    headers.remove(i);
  }

  let body = match req.body_mut().collect().await {
    Ok(body) => body.to_bytes(),
    Err(e) => {
      error!("Failed to collect request body: {}", e);
      let response = Response::builder()
        .status(StatusCode::BAD_REQUEST)
        .body(Full::new(Bytes::from("Bad Request")))
        .unwrap();
      return Ok(response);
    }
  };

  debug!("{url} {:?}", headers);
  match fetch.run(method, url, headers, Some(body)).await {
    Ok(res) => {
      let mut builder = Response::builder().status(res.status);
      for (key, value) in res.headers {
        if let Some(key) = key {
          builder = builder.header(key, value);
        }
      }
      Ok(builder.body(Full::new(res.body)).unwrap())
    }
    Err(e) => {
      error!("Fetch error: {}", e);
      Ok(
        Response::builder()
          .status(StatusCode::INTERNAL_SERVER_ERROR)
          .body(Full::new(Bytes::from("Internal Server Error")))
          .unwrap(),
      )
    }
  }
}