aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVojtěch Pejša <vojtechpejsa7@gmail.com>2019-03-26 20:38:57 +0000
committerVojtěch Pejša <vojtechpejsa7@gmail.com>2019-04-04 08:51:00 +0000
commitc6e5fef650e6b9e286f9d918e3cb730372d78892 (patch)
treedf7339ce71fcdcca571f270f91276a5cc85d3171
parentDocument file upload. (diff)
downloadminiserve-c6e5fef650e6b9e286f9d918e3cb730372d78892.tar.gz
miniserve-c6e5fef650e6b9e286f9d918e3cb730372d78892.zip
Use proper typed query param.
-rw-r--r--src/file_upload.rs41
1 files changed, 25 insertions, 16 deletions
diff --git a/src/file_upload.rs b/src/file_upload.rs
index c0ec95f..dd4c962 100644
--- a/src/file_upload.rs
+++ b/src/file_upload.rs
@@ -1,14 +1,21 @@
use actix_web::{
dev, error,
http::header::{ContentDisposition, LOCATION},
- multipart, Error, FutureResponse, HttpMessage, HttpRequest, HttpResponse,
+ multipart, Error, FromRequest, FutureResponse, HttpMessage, HttpRequest, HttpResponse, Query,
};
use futures::{future, Future, Stream};
+use serde::Deserialize;
use std::{
io::Write,
path::{Component, PathBuf},
};
+/// Query parameters
+#[derive(Debug, Deserialize)]
+struct QueryParameters {
+ path: PathBuf,
+}
+
/// Create future to save file.
fn save_file(
field: multipart::Field<dev::Payload>,
@@ -73,22 +80,24 @@ fn handle_multipart(
/// invalid.
/// This method returns future.
pub fn upload_file(req: &HttpRequest<crate::MiniserveConfig>) -> FutureResponse<HttpResponse> {
- if !req.query().contains_key("path") {
- return Box::new(future::ok(
- HttpResponse::BadRequest().body("Unspecified parameter path"),
- ));
- }
- // server root path should be valid so we can unwrap it
let app_root_dir = req.state().path.clone().canonicalize().unwrap();
-
- let path_str = req.query()["path"].clone();
- let mut path = PathBuf::from(path_str.clone());
- if let Ok(stripped_path) = path.strip_prefix(Component::RootDir) {
- path = stripped_path.to_owned();
- }
+ let path = match Query::<QueryParameters>::extract(req) {
+ Ok(query) => {
+ if let Ok(stripped_path) = query.path.strip_prefix(Component::RootDir) {
+ stripped_path.to_owned()
+ } else {
+ query.path.clone()
+ }
+ }
+ Err(_) => {
+ return Box::new(future::ok(
+ HttpResponse::BadRequest().body("Unspecified parameter path"),
+ ))
+ }
+ };
// if target path is under app root directory save file
- let target_dir = match &app_root_dir.clone().join(path).canonicalize() {
+ let target_dir = match &app_root_dir.clone().join(path.clone()).canonicalize() {
Ok(path) if path.starts_with(&app_root_dir) => path.clone(),
_ => return Box::new(future::ok(HttpResponse::BadRequest().body("Invalid path"))),
};
@@ -98,9 +107,9 @@ pub fn upload_file(req: &HttpRequest<crate::MiniserveConfig>) -> FutureResponse<
.map(move |item| handle_multipart(item, target_dir.clone()))
.flatten()
.collect()
- .map(|_| {
+ .map(move |_| {
HttpResponse::TemporaryRedirect()
- .header(LOCATION, path_str)
+ .header(LOCATION, format!("{}", path.display()))
.finish()
})
.map_err(|e| e),