use http_types::Url;
use tide::{Request, Result};
use crate::serve::State;
pub struct ProxyHandlerHttp {
backend: Url,
rewrite: Option<String>,
}
impl ProxyHandlerHttp {
pub fn new(backend: Url, rewrite: Option<String>) -> Self {
Self { backend, rewrite }
}
pub fn path(&self) -> &str {
self.rewrite.as_ref().map(AsRef::as_ref).unwrap_or_else(|| self.backend.path())
}
pub async fn proxy_request(&self, mut req: Request<State>) -> Result {
let req_url = req.url();
let req_path = req_url.path();
let mut url = self.backend.clone();
if let Ok(mut segments) = url.path_segments_mut() {
segments.pop_if_empty().extend(req_path.trim_start_matches('/').split('/'));
}
url.set_query(req_url.query());
let mut request = surf::RequestBuilder::new(req.method(), url).body(req.take_body());
for (hname, hval) in req.iter() {
request = request.header(hname, hval);
}
if let Some(host) = self.backend.host_str() {
request = request.header("host", host);
}
let mut res = request.send().await?;
let mut response = tide::Response::builder(res.status()).body(res.take_body());
for (hname, hval) in res.iter() {
response = response.header(hname, hval);
}
Ok(response.build())
}
}