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,
|
||||
};
|
||||
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;
|
||||
|
|
Reference in New Issue