1use crate::http::response::ResponseError;
4use crate::http::{Request, Response, StatusCode};
5
6use std::io::Write;
7use std::net::{SocketAddr, TcpStream};
8use std::time::Duration;
9
10pub fn proxy_request(request: &Request, target: SocketAddr, timeout: Duration) -> Response {
13 match proxy_request_internal(request, target, timeout) {
14 Ok(response) => response,
15 Err(_) => Response::empty(StatusCode::BadGateway)
16 .with_bytes(b"<html><body><h1>502 Bad Gateway</h1></body></html>"),
17 }
18}
19
20fn proxy_request_internal(
21 request: &Request,
22 target: SocketAddr,
23 timeout: Duration,
24) -> Result<Response, ResponseError> {
25 let mut stream =
26 TcpStream::connect_timeout(&target, timeout).map_err(|_| ResponseError::Stream)?;
27
28 let mut cloned_request = request.clone();
29 cloned_request
30 .headers
31 .add("X-Forwarded-For", request.address.origin_addr.to_string());
32 let request_bytes: Vec<u8> = cloned_request.into();
33 stream
34 .write_all(&request_bytes)
35 .map_err(|_| ResponseError::Stream)?;
36
37 Response::from_stream(&mut stream)
38}