Basic proxy without data works

proxy
Jef Roosens 2021-11-26 13:15:47 +01:00
parent 7804db5ff0
commit b442e352b3
Signed by: Jef Roosens
GPG Key ID: B580B976584B5F30
4 changed files with 36 additions and 18 deletions

2
Cargo.lock generated
View File

@ -1162,6 +1162,7 @@ name = "rb-gw"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"base64", "base64",
"bytes",
"chrono", "chrono",
"diesel", "diesel",
"diesel_migrations", "diesel_migrations",
@ -1177,6 +1178,7 @@ dependencies = [
"rust-argon2", "rust-argon2",
"serde", "serde",
"sha2", "sha2",
"tokio-util",
"uuid", "uuid",
] ]

View File

@ -40,6 +40,8 @@ base64 = "0.13.0"
figment = { version = "*", features = [ "yaml" ] } figment = { version = "*", features = [ "yaml" ] }
mimalloc = { version = "0.1.26", default_features = false } mimalloc = { version = "0.1.26", default_features = false }
reqwest = { version = "0.11.6", features = [ "stream" ] } reqwest = { version = "0.11.6", features = [ "stream" ] }
tokio-util = {version="*", features=["io"]}
bytes = "*"
[profile.dev] [profile.dev]
lto = "off" lto = "off"

View File

@ -129,10 +129,10 @@ fn rocket() -> _
.expect("services config"); .expect("services config");
rocket rocket
.mount("/v1/posts", ProxyServer::from(services_conf.blog.clone())) .mount("/api/v1/posts", ProxyServer::from(&services_conf.blog, "/v1/posts"))
.mount( .mount(
"/v1/sections", "/api/v1/sections",
ProxyServer::from(services_conf.blog.clone()), ProxyServer::from(&services_conf.blog, "/v1/sections"),
) )
.manage(jwt_conf) .manage(jwt_conf)
.manage(admin_conf) .manage(admin_conf)

View File

@ -1,11 +1,13 @@
use std::path::{Path, PathBuf};
use reqwest::{ use reqwest::{
header::{HeaderMap, HeaderName, HeaderValue}, header::{HeaderMap, HeaderName, HeaderValue},
Method as ReqMethod, Method as ReqMethod,
}; };
use rocket::{ use rocket::{
response::stream::ByteStream,
data::ToByteUnit, data::ToByteUnit,
http::{ Method, Header }, http::{Header, Method},
response::Redirect, response::{Redirect},
route::{Handler, Outcome}, route::{Handler, Outcome},
Data, Request, Route, Data, Request, Route,
}; };
@ -14,6 +16,7 @@ use rocket::{
pub struct ProxyServer pub struct ProxyServer
{ {
root: String, root: String,
prefix: PathBuf,
rank: isize, rank: isize,
} }
@ -21,14 +24,14 @@ impl ProxyServer
{ {
const DEFAULT_RANK: isize = 0; const DEFAULT_RANK: isize = 0;
pub fn new(root: String, rank: isize) -> Self pub fn new<P: AsRef<Path>>(root: &str, prefix: P, rank: isize) -> Self
{ {
ProxyServer { root, rank } ProxyServer { root: String::from(root), prefix: prefix.as_ref().into(), rank }
} }
pub fn from(root: String) -> Self pub fn from<P: AsRef<Path>>(root: &str, prefix: P) -> Self
{ {
Self::new(root, Self::DEFAULT_RANK) Self::new(root, prefix, Self::DEFAULT_RANK)
} }
} }
@ -49,7 +52,7 @@ impl Into<Vec<Route>> for ProxyServer
for method in METHODS { for method in METHODS {
let mut route = Route::ranked(self.rank, method, "/<path..>", self.clone()); let mut route = Route::ranked(self.rank, method, "/<path..>", self.clone());
route.name = route.name =
Some(format!("ProxyServer: {} {}", method.as_str(), self.root.clone()).into()); Some(format!("ProxyServer: {} {}{}", method.as_str(), self.root.clone(), self.prefix.to_str().unwrap()).into());
routes.push(route); routes.push(route);
} }
@ -88,7 +91,16 @@ impl Handler for ProxyServer
}; };
// Then the URL // Then the URL
let url = format!("{}{}?{}", self.root, req.uri().path().as_str(), req.uri().query().unwrap()); // We first extract all URL segments starting from the mountpoint
let segments: PathBuf = req.segments(0..).unwrap();
let url = format!(
"{}{}/{}?{}",
self.root,
self.prefix.to_str().unwrap(),
segments.to_str().unwrap(),
req.uri().query().unwrap()
);
// And finally, the data // And finally, the data
// TODO don't hard-code max request size here // TODO don't hard-code max request size here
@ -111,17 +123,19 @@ impl Handler for ProxyServer
.unwrap(); .unwrap();
println!("{:?}", new_res); println!("{:?}", new_res);
let mut rocket_res = rocket::Response::new(); let mut res_builder = rocket::Response::build();
rocket_res.set_status(rocket::http::Status::new(new_res.status().as_u16())); let mut res_builder = res_builder.status(rocket::http::Status::new(new_res.status().as_u16()));
// rocket_res.set_streamed_body(new_res.bytes_stream()); // .streamed_body(ByteStream::from(new_res.bytes_stream()));
// reqwest headers -> rocket headers // reqwest headers -> rocket headers
for (key, value) in new_res.headers().clone().iter_mut() { for (key, value) in new_res.headers().clone().iter_mut() {
println!("{}", rocket_res.set_raw_header(String::from(key.clone().as_str()), String::from(value.clone().to_str().unwrap()))); res_builder = res_builder.raw_header(
String::from(key.clone().as_str()),
String::from(value.clone().to_str().unwrap())
);
} }
println!("{:?}", rocket_res); Outcome::Success(res_builder.finalize())
Outcome::Success(rocket_res)
} }
} }