mirror of
https://github.com/fafhrd91/actix-web
synced 2025-08-28 07:47:49 +02:00
split up files lib (#1685)
This commit is contained in:
99
actix-files/src/path_buf.rs
Normal file
99
actix-files/src/path_buf.rs
Normal file
@@ -0,0 +1,99 @@
|
||||
use std::{
|
||||
path::{Path, PathBuf},
|
||||
str::FromStr,
|
||||
};
|
||||
|
||||
use actix_web::{dev::Payload, FromRequest, HttpRequest};
|
||||
use futures_util::future::{ready, Ready};
|
||||
|
||||
use crate::error::UriSegmentError;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct PathBufWrap(PathBuf);
|
||||
|
||||
impl FromStr for PathBufWrap {
|
||||
type Err = UriSegmentError;
|
||||
|
||||
fn from_str(path: &str) -> Result<Self, Self::Err> {
|
||||
let mut buf = PathBuf::new();
|
||||
|
||||
for segment in path.split('/') {
|
||||
if segment == ".." {
|
||||
buf.pop();
|
||||
} else if segment.starts_with('.') {
|
||||
return Err(UriSegmentError::BadStart('.'));
|
||||
} else if segment.starts_with('*') {
|
||||
return Err(UriSegmentError::BadStart('*'));
|
||||
} else if segment.ends_with(':') {
|
||||
return Err(UriSegmentError::BadEnd(':'));
|
||||
} else if segment.ends_with('>') {
|
||||
return Err(UriSegmentError::BadEnd('>'));
|
||||
} else if segment.ends_with('<') {
|
||||
return Err(UriSegmentError::BadEnd('<'));
|
||||
} else if segment.is_empty() {
|
||||
continue;
|
||||
} else if cfg!(windows) && segment.contains('\\') {
|
||||
return Err(UriSegmentError::BadChar('\\'));
|
||||
} else {
|
||||
buf.push(segment)
|
||||
}
|
||||
}
|
||||
|
||||
Ok(PathBufWrap(buf))
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<Path> for PathBufWrap {
|
||||
fn as_ref(&self) -> &Path {
|
||||
self.0.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl FromRequest for PathBufWrap {
|
||||
type Error = UriSegmentError;
|
||||
type Future = Ready<Result<Self, Self::Error>>;
|
||||
type Config = ();
|
||||
|
||||
fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
|
||||
ready(req.match_info().path().parse())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::iter::FromIterator;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_path_buf() {
|
||||
assert_eq!(
|
||||
PathBufWrap::from_str("/test/.tt").map(|t| t.0),
|
||||
Err(UriSegmentError::BadStart('.'))
|
||||
);
|
||||
assert_eq!(
|
||||
PathBufWrap::from_str("/test/*tt").map(|t| t.0),
|
||||
Err(UriSegmentError::BadStart('*'))
|
||||
);
|
||||
assert_eq!(
|
||||
PathBufWrap::from_str("/test/tt:").map(|t| t.0),
|
||||
Err(UriSegmentError::BadEnd(':'))
|
||||
);
|
||||
assert_eq!(
|
||||
PathBufWrap::from_str("/test/tt<").map(|t| t.0),
|
||||
Err(UriSegmentError::BadEnd('<'))
|
||||
);
|
||||
assert_eq!(
|
||||
PathBufWrap::from_str("/test/tt>").map(|t| t.0),
|
||||
Err(UriSegmentError::BadEnd('>'))
|
||||
);
|
||||
assert_eq!(
|
||||
PathBufWrap::from_str("/seg1/seg2/").unwrap().0,
|
||||
PathBuf::from_iter(vec!["seg1", "seg2"])
|
||||
);
|
||||
assert_eq!(
|
||||
PathBufWrap::from_str("/seg1/../seg2/").unwrap().0,
|
||||
PathBuf::from_iter(vec!["seg2"])
|
||||
);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user