diff options
author | boastful-squirrel <boastful.squirrel@gmail.com> | 2019-04-26 17:09:17 +0000 |
---|---|---|
committer | boastful-squirrel <boastful.squirrel@gmail.com> | 2019-04-26 17:09:17 +0000 |
commit | 111a3dc44730e0e24a5aa4218e8e385b236a619d (patch) | |
tree | 86cc6947f1d3ae0d803a80c3a4ee22b033cb511f /src/file_upload.rs | |
parent | Cargo fmt (diff) | |
download | miniserve-111a3dc44730e0e24a5aa4218e8e385b236a619d.tar.gz miniserve-111a3dc44730e0e24a5aa4218e8e385b236a619d.zip |
Merged query parameter structs + improved file upload errors
Diffstat (limited to 'src/file_upload.rs')
-rw-r--r-- | src/file_upload.rs | 54 |
1 files changed, 33 insertions, 21 deletions
diff --git a/src/file_upload.rs b/src/file_upload.rs index 1618617..f444396 100644 --- a/src/file_upload.rs +++ b/src/file_upload.rs @@ -3,22 +3,16 @@ use actix_web::{ HttpResponse, Query, }; use futures::{future, future::FutureResult, Future, Stream}; -use serde::Deserialize; use std::{ fs, io::Write, path::{Component, PathBuf}, }; -use crate::errors::{self, ContextualErrorKind}; +use crate::errors::{self, ContextualError, ContextualErrorKind}; +use crate::listing::QueryParameters; use crate::renderer; -/// Query parameters -#[derive(Debug, Deserialize)] -struct QueryParameters { - path: PathBuf, -} - /// Create future to save file. fn save_file( field: multipart::Field<dev::Payload>, @@ -127,31 +121,49 @@ pub fn upload_file(req: &HttpRequest<crate::MiniserveConfig>) -> FutureResponse< } else { "/".to_string() }; - let app_root_dir = if let Ok(dir) = req.state().path.canonicalize() { - dir - } else { - return Box::new(create_error_response("Internal server error", &return_path)); + + let app_root_dir = match req.state().path.canonicalize() { + Ok(dir) => dir, + Err(e) => { + let err = ContextualError::new(ContextualErrorKind::IOError( + "Failed to resolve path served by miniserve".to_string(), + e, + )); + return Box::new(create_error_response(&err.to_string(), &return_path)); + } }; + let path = match Query::<QueryParameters>::extract(req) { Ok(query) => { - if let Ok(stripped_path) = query.path.strip_prefix(Component::RootDir) { - stripped_path.to_owned() + if let Some(path) = query.path.clone() { + if let Ok(stripped_path) = path.strip_prefix(Component::RootDir) { + stripped_path.to_owned() + } else { + path.clone() + } } else { - query.path.clone() + let err = ContextualError::new(ContextualErrorKind::InvalidHTTPRequestError( + "Missing query parameter 'path'".to_string(), + )); + return Box::new(create_error_response(&err.to_string(), &return_path)); } } - Err(_) => { - return Box::new(create_error_response( - "Unspecified parameter path", - &return_path, - )) + Err(e) => { + let err = + ContextualError::new(ContextualErrorKind::InvalidHTTPRequestError(e.to_string())); + return Box::new(create_error_response(&err.to_string(), &return_path)); } }; // If the target path is under the app root directory, save the file. let target_dir = match &app_root_dir.clone().join(path).canonicalize() { Ok(path) if path.starts_with(&app_root_dir) => path.clone(), - _ => return Box::new(create_error_response("Invalid path", &return_path)), + _ => { + let err = ContextualError::new(ContextualErrorKind::InvalidHTTPRequestError( + "Invalid value for 'path' parameter".to_string(), + )); + return Box::new(create_error_response(&err.to_string(), &return_path)); + } }; let overwrite_files = req.state().overwrite_files; Box::new( |