First working proxy!

This commit is contained in:
Jef Roosens 2021-11-26 20:49:45 +01:00
parent 1ed62dc18c
commit 84b9afbd1b
Signed by: Jef Roosens
GPG key ID: B580B976584B5F30
3 changed files with 49 additions and 21 deletions

View file

@ -1,16 +1,21 @@
use std::path::{Path, PathBuf};
use std::{
io::Cursor,
path::{Path, PathBuf},
};
use futures::stream::TryStreamExt;
use reqwest::{
header::{HeaderMap, HeaderName, HeaderValue},
Method as ReqMethod,
};
use rocket::{
response::stream::ByteStream,
data::ToByteUnit,
http::{Header, Method},
response::{Redirect},
response::{stream::ByteStream, Redirect},
route::{Handler, Outcome},
Data, Request, Route,
};
use tokio_util::compat::FuturesAsyncReadCompatExt;
#[derive(Clone)]
pub struct ProxyServer
@ -26,7 +31,11 @@ impl ProxyServer
pub fn new<P: AsRef<Path>>(root: &str, prefix: P, rank: isize) -> Self
{
ProxyServer { root: String::from(root), prefix: prefix.as_ref().into(), rank }
ProxyServer {
root: String::from(root),
prefix: prefix.as_ref().into(),
rank,
}
}
pub fn from<P: AsRef<Path>>(root: &str, prefix: P) -> Self
@ -51,8 +60,15 @@ impl Into<Vec<Route>> for ProxyServer
for method in METHODS {
let mut route = Route::ranked(self.rank, method, "/<path..>", self.clone());
route.name =
Some(format!("ProxyServer: {} {}{}", method.as_str(), self.root.clone(), self.prefix.to_str().unwrap()).into());
route.name = Some(
format!(
"ProxyServer: {} {}{}",
method.as_str(),
self.root.clone(),
self.prefix.to_str().unwrap()
)
.into(),
);
routes.push(route);
}
@ -94,7 +110,10 @@ impl Handler for ProxyServer
// We first extract all URL segments starting from the mountpoint
let segments: PathBuf = req.segments(0..).unwrap();
let query_part = req.uri().query().map_or(String::from(""), |s| format!("?{}", s));
let query_part = req
.uri()
.query()
.map_or(String::from(""), |s| format!("?{}", s));
let url = format!(
"{}{}/{}{}",
@ -123,19 +142,25 @@ impl Handler for ProxyServer
.send()
.await
.unwrap();
println!("{:?}", new_res);
let mut res_headers = new_res.headers().clone();
let mut res_builder = rocket::Response::build();
let mut res_builder = res_builder.status(rocket::http::Status::new(new_res.status().as_u16()));
// .streamed_body(ByteStream::from(new_res.bytes_stream()));
// reqwest headers -> rocket headers
for (key, value) in new_res.headers().clone().iter_mut() {
res_builder = res_builder.raw_header(
String::from(key.clone().as_str()),
String::from(value.clone().to_str().unwrap())
let mut res_builder = res_builder
.status(rocket::http::Status::new(new_res.status().as_u16()))
.streamed_body(
new_res
.bytes_stream()
.map_err(|e| futures::io::Error::new(futures::io::ErrorKind::Other, e))
.into_async_read()
.compat(),
);
// reqwest headers -> rocket headers
for (key, value) in res_headers.iter_mut() {
res_builder = res_builder.raw_header(
String::from(key.clone().as_str()),
String::from(value.clone().to_str().unwrap()),
);
}
Outcome::Success(res_builder.finalize())