Added better uri parsing (inspired by FileServer)
parent
d78e35a2f5
commit
1e0fd05969
58
src/proxy.rs
58
src/proxy.rs
|
@ -6,6 +6,8 @@ use reqwest::{
|
||||||
Method as ReqMethod,
|
Method as ReqMethod,
|
||||||
};
|
};
|
||||||
use rocket::{
|
use rocket::{
|
||||||
|
http::uri::Segments,
|
||||||
|
fs::Options,
|
||||||
data::ToByteUnit,
|
data::ToByteUnit,
|
||||||
http::{Method, Status},
|
http::{Method, Status},
|
||||||
route::{Handler, Outcome},
|
route::{Handler, Outcome},
|
||||||
|
@ -19,24 +21,26 @@ pub struct ProxyServer
|
||||||
root: String,
|
root: String,
|
||||||
prefix: PathBuf,
|
prefix: PathBuf,
|
||||||
rank: isize,
|
rank: isize,
|
||||||
|
options: Options,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ProxyServer
|
impl ProxyServer
|
||||||
{
|
{
|
||||||
const DEFAULT_RANK: isize = 0;
|
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 {
|
ProxyServer {
|
||||||
root: String::from(root),
|
root: String::from(root),
|
||||||
prefix: prefix.as_ref().into(),
|
prefix: prefix.as_ref().into(),
|
||||||
rank,
|
rank,
|
||||||
|
options,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from<P: AsRef<Path>>(root: &str, prefix: P) -> Self
|
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>
|
async fn handle<'r>(&self, req: &'r Request<'_>, data: Data<'r>) -> Outcome<'r>
|
||||||
{
|
{
|
||||||
|
use rocket::http::uri::fmt::Path;
|
||||||
|
|
||||||
// ROCKET REQUEST -> REQWEST REQUEST
|
// 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
|
// Headers
|
||||||
let mut headers = HeaderMap::new();
|
let mut headers = HeaderMap::new();
|
||||||
|
@ -106,26 +140,6 @@ impl Handler for ProxyServer
|
||||||
_ => todo!(),
|
_ => 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
|
// And finally, the data
|
||||||
// TODO don't hard-code max request size here
|
// TODO don't hard-code max request size here
|
||||||
static BODY_SIZE: i64 = 2;
|
static BODY_SIZE: i64 = 2;
|
||||||
|
|
Reference in New Issue