Added better uri parsing (inspired by FileServer)

proxy
Jef Roosens 2021-11-26 22:36:24 +01:00
parent d78e35a2f5
commit 1e0fd05969
Signed by: Jef Roosens
GPG Key ID: 955C0660072F691F
1 changed files with 36 additions and 22 deletions

View File

@ -6,6 +6,8 @@ use reqwest::{
Method as ReqMethod,
};
use rocket::{
http::uri::Segments,
fs::Options,
data::ToByteUnit,
http::{Method, Status},
route::{Handler, Outcome},
@ -19,24 +21,26 @@ pub struct ProxyServer
root: String,
prefix: PathBuf,
rank: isize,
options: Options,
}
impl ProxyServer
{
const DEFAULT_RANK: isize = 0;
pub fn new<P: AsRef<Path>>(root: &str, prefix: P, rank: isize) -> Self
pub fn new<P: AsRef<Path>>(root: &str, prefix: P, rank: isize, options: Options) -> Self
{
ProxyServer {
root: String::from(root),
prefix: prefix.as_ref().into(),
rank,
options,
}
}
pub fn from<P: AsRef<Path>>(root: &str, prefix: P) -> Self
{
Self::new(root, prefix, Self::DEFAULT_RANK)
Self::new(root, prefix, Self::DEFAULT_RANK, Options::NormalizeDirs)
}
}
@ -78,7 +82,37 @@ impl Handler for ProxyServer
{
async fn handle<'r>(&self, req: &'r Request<'_>, data: Data<'r>) -> Outcome<'r>
{
use rocket::http::uri::fmt::Path;
// ROCKET REQUEST -> REQWEST REQUEST
// Path
let allow_dotfiles = self.options.contains(Options::DotFiles);
let path = req.segments::<Segments<'_, Path>>(0..).ok()
.and_then(|segments| segments.to_path_buf(allow_dotfiles).ok())
.map(|path| self.prefix.join(path));
if path.is_none() {
return Outcome::Failure(Status::BadRequest);
}
let path_val = path.unwrap();
let path_str = path_val.to_str(); // Unwrap is safe because we check for is_none() beforehand
if path_str.is_none() {
return Outcome::Failure(Status::BadRequest);
}
let query_part = req
.uri()
.query()
.map_or(String::from(""), |s| format!("?{}", s));
let url = format!(
"{}{}{}",
self.root,
path_str.unwrap(), // Unwrap is safe because we check for is_none() beforehand
query_part
);
// Headers
let mut headers = HeaderMap::new();
@ -106,26 +140,6 @@ impl Handler for ProxyServer
_ => todo!(),
};
// URL
// We first extract all URL segments starting from the mountpoint
let segments: PathBuf = match req.segments(0..) {
Ok(val) => val,
Err(_) => return Outcome::Failure(Status::InternalServerError),
};
let query_part = req
.uri()
.query()
.map_or(String::from(""), |s| format!("?{}", s));
let url = format!(
"{}{}/{}{}",
self.root,
self.prefix.to_str().unwrap_or(""),
segments.to_str().unwrap_or(""),
query_part
);
// And finally, the data
// TODO don't hard-code max request size here
static BODY_SIZE: i64 = 2;