From 111a3dc44730e0e24a5aa4218e8e385b236a619d Mon Sep 17 00:00:00 2001 From: boastful-squirrel Date: Fri, 26 Apr 2019 19:09:17 +0200 Subject: Merged query parameter structs + improved file upload errors --- src/file_upload.rs | 54 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 21 deletions(-) (limited to 'src/file_upload.rs') 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, @@ -127,31 +121,49 @@ pub fn upload_file(req: &HttpRequest) -> 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::::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( -- cgit v1.2.3 From fd3392636ce013cf8193a0881fa08680a8239698 Mon Sep 17 00:00:00 2001 From: boastful-squirrel Date: Sat, 27 Apr 2019 12:12:42 +0200 Subject: Themed errors --- src/file_upload.rs | 108 ++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 86 insertions(+), 22 deletions(-) (limited to 'src/file_upload.rs') diff --git a/src/file_upload.rs b/src/file_upload.rs index f444396..88a4649 100644 --- a/src/file_upload.rs +++ b/src/file_upload.rs @@ -10,8 +10,9 @@ use std::{ }; use crate::errors::{self, ContextualError, ContextualErrorKind}; -use crate::listing::QueryParameters; +use crate::listing::{QueryParameters, SortingMethod, SortingOrder}; use crate::renderer; +use crate::themes::ColorScheme; /// Create future to save file. fn save_file( @@ -29,7 +30,7 @@ fn save_file( Ok(file) => file, Err(e) => { return Box::new(future::err(ContextualErrorKind::IOError( - format!("Failed to create file in {}", file_path.display()), + format!("Failed to create file {}", file_path.display()), e, ))); } @@ -115,43 +116,77 @@ fn handle_multipart( /// server root directory. Any path which will go outside of this directory is considered /// invalid. /// This method returns future. -pub fn upload_file(req: &HttpRequest) -> FutureResponse { +pub fn upload_file( + req: &HttpRequest, + default_color_scheme: ColorScheme, +) -> FutureResponse { let return_path = if let Some(header) = req.headers().get(header::REFERER) { header.to_str().unwrap_or("/").to_owned() } else { "/".to_string() }; - 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::::extract(req) { + let (path, sort_method, sort_order, color_scheme) = match Query::::extract(req) + { Ok(query) => { + let sort_param = query.sort; + let order_param = query.order; + let theme_param = query.theme.unwrap_or(default_color_scheme); + if let Some(path) = query.path.clone() { if let Ok(stripped_path) = path.strip_prefix(Component::RootDir) { - stripped_path.to_owned() + ( + stripped_path.to_owned(), + sort_param, + order_param, + theme_param, + ) } else { - path.clone() + (path.clone(), sort_param, order_param, theme_param) } } else { let err = ContextualError::new(ContextualErrorKind::InvalidHTTPRequestError( "Missing query parameter 'path'".to_string(), )); - return Box::new(create_error_response(&err.to_string(), &return_path)); + return Box::new(create_error_response( + &err.to_string(), + &return_path, + sort_param, + order_param, + theme_param, + default_color_scheme, + )); } } Err(e) => { let err = ContextualError::new(ContextualErrorKind::InvalidHTTPRequestError(e.to_string())); - return Box::new(create_error_response(&err.to_string(), &return_path)); + return Box::new(create_error_response( + &err.to_string(), + &return_path, + None, + None, + default_color_scheme, + default_color_scheme, + )); + } + }; + + 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, + sort_method, + sort_order, + color_scheme, + default_color_scheme, + )); } }; @@ -162,7 +197,14 @@ pub fn upload_file(req: &HttpRequest) -> FutureResponse< let err = ContextualError::new(ContextualErrorKind::InvalidHTTPRequestError( "Invalid value for 'path' parameter".to_string(), )); - return Box::new(create_error_response(&err.to_string(), &return_path)); + return Box::new(create_error_response( + &err.to_string(), + &return_path, + sort_method, + sort_order, + color_scheme, + default_color_scheme, + )); } }; let overwrite_files = req.state().overwrite_files; @@ -178,7 +220,14 @@ pub fn upload_file(req: &HttpRequest) -> FutureResponse< .header(header::LOCATION, return_path.to_string()) .finish(), ), - Err(e) => create_error_response(&e.to_string(), &return_path), + Err(e) => create_error_response( + &e.to_string(), + &return_path, + sort_method, + sort_order, + color_scheme, + default_color_scheme, + ), }), ) } @@ -187,11 +236,26 @@ pub fn upload_file(req: &HttpRequest) -> FutureResponse< fn create_error_response( description: &str, return_path: &str, + sorting_method: Option, + sorting_order: Option, + color_scheme: ColorScheme, + default_color_scheme: ColorScheme, ) -> FutureResult { errors::log_error_chain(description.to_string()); future::ok( HttpResponse::BadRequest() .content_type("text/html; charset=utf-8") - .body(renderer::render_error(description, return_path).into_string()), + .body( + renderer::render_error( + description, + return_path, + sorting_method, + sorting_order, + color_scheme, + default_color_scheme, + true, + ) + .into_string(), + ), ) } -- cgit v1.2.3 From 211250a71d9b2df27f85beb35b89d23346c6fa5e Mon Sep 17 00:00:00 2001 From: boastful-squirrel Date: Sat, 27 Apr 2019 12:25:11 +0200 Subject: Improved some errors --- src/file_upload.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/file_upload.rs') diff --git a/src/file_upload.rs b/src/file_upload.rs index 88a4649..f8c5019 100644 --- a/src/file_upload.rs +++ b/src/file_upload.rs @@ -30,7 +30,7 @@ fn save_file( Ok(file) => file, Err(e) => { return Box::new(future::err(ContextualErrorKind::IOError( - format!("Failed to create file {}", file_path.display()), + format!("Failed to create {}", file_path.display()), e, ))); } -- cgit v1.2.3 From fa0c2865366b1bb65a2977c4b9608c9a92fc5889 Mon Sep 17 00:00:00 2001 From: boastful-squirrel Date: Wed, 1 May 2019 18:23:29 +0200 Subject: Use HTTP StatusCode for error title --- src/file_upload.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src/file_upload.rs') diff --git a/src/file_upload.rs b/src/file_upload.rs index 46a3a1f..1d854bf 100644 --- a/src/file_upload.rs +++ b/src/file_upload.rs @@ -1,5 +1,5 @@ use actix_web::{ - dev, http::header, multipart, FromRequest, FutureResponse, HttpMessage, HttpRequest, + dev, http::{header, StatusCode}, multipart, FromRequest, FutureResponse, HttpMessage, HttpRequest, HttpResponse, Query, }; use futures::{future, future::FutureResult, Future, Stream}; @@ -150,6 +150,7 @@ pub fn upload_file( ); return Box::new(create_error_response( &err.to_string(), + StatusCode::BAD_REQUEST, &return_path, sort_param, order_param, @@ -162,6 +163,7 @@ pub fn upload_file( let err = ContextualError::InvalidHTTPRequestError(e.to_string()); return Box::new(create_error_response( &err.to_string(), + StatusCode::BAD_REQUEST, &return_path, None, None, @@ -180,6 +182,7 @@ pub fn upload_file( ); return Box::new(create_error_response( &err.to_string(), + StatusCode::INTERNAL_SERVER_ERROR, &return_path, sort_method, sort_order, @@ -198,6 +201,7 @@ pub fn upload_file( ); return Box::new(create_error_response( &err.to_string(), + StatusCode::BAD_REQUEST, &return_path, sort_method, sort_order, @@ -221,6 +225,7 @@ pub fn upload_file( ), Err(e) => create_error_response( &e.to_string(), + StatusCode::INTERNAL_SERVER_ERROR, &return_path, sort_method, sort_order, @@ -234,6 +239,7 @@ pub fn upload_file( /// Convenience method for creating response errors, if file upload fails. fn create_error_response( description: &str, + error_code: StatusCode, return_path: &str, sorting_method: Option, sorting_order: Option, @@ -247,6 +253,7 @@ fn create_error_response( .body( renderer::render_error( description, + error_code, return_path, sorting_method, sorting_order, -- cgit v1.2.3 From 321b0ce7a693780830780f19de1cdec31657d2db Mon Sep 17 00:00:00 2001 From: boastful-squirrel Date: Thu, 2 May 2019 07:23:38 +0200 Subject: Cargo fmt --- src/file_upload.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/file_upload.rs') diff --git a/src/file_upload.rs b/src/file_upload.rs index 1d854bf..9344e8b 100644 --- a/src/file_upload.rs +++ b/src/file_upload.rs @@ -1,6 +1,7 @@ use actix_web::{ - dev, http::{header, StatusCode}, multipart, FromRequest, FutureResponse, HttpMessage, HttpRequest, - HttpResponse, Query, + dev, + http::{header, StatusCode}, + multipart, FromRequest, FutureResponse, HttpMessage, HttpRequest, HttpResponse, Query, }; use futures::{future, future::FutureResult, Future, Stream}; use std::{ -- cgit v1.2.3 From dd8d11c698435217c370b940b41d060a614892c1 Mon Sep 17 00:00:00 2001 From: boastful-squirrel Date: Thu, 2 May 2019 21:36:47 +0200 Subject: Read query params to handle error back link --- src/file_upload.rs | 59 +++++++++++++++++------------------------------------- 1 file changed, 18 insertions(+), 41 deletions(-) (limited to 'src/file_upload.rs') diff --git a/src/file_upload.rs b/src/file_upload.rs index 9344e8b..36b2401 100644 --- a/src/file_upload.rs +++ b/src/file_upload.rs @@ -1,7 +1,7 @@ use actix_web::{ dev, http::{header, StatusCode}, - multipart, FromRequest, FutureResponse, HttpMessage, HttpRequest, HttpResponse, Query, + multipart, FutureResponse, HttpMessage, HttpRequest, HttpResponse, }; use futures::{future, future::FutureResult, Future, Stream}; use std::{ @@ -11,7 +11,7 @@ use std::{ }; use crate::errors::{self, ContextualError}; -use crate::listing::{QueryParameters, SortingMethod, SortingOrder}; +use crate::listing::{self, SortingMethod, SortingOrder}; use crate::renderer; use crate::themes::ColorScheme; @@ -127,48 +127,24 @@ pub fn upload_file( "/".to_string() }; - let (path, sort_method, sort_order, color_scheme) = match Query::::extract(req) - { - Ok(query) => { - let sort_param = query.sort; - let order_param = query.order; - let theme_param = query.theme.unwrap_or(default_color_scheme); - - if let Some(path) = query.path.clone() { - if let Ok(stripped_path) = path.strip_prefix(Component::RootDir) { - ( - stripped_path.to_owned(), - sort_param, - order_param, - theme_param, - ) - } else { - (path.clone(), sort_param, order_param, theme_param) - } - } else { - let err = ContextualError::InvalidHTTPRequestError( - "Missing query parameter 'path'".to_string(), - ); - return Box::new(create_error_response( - &err.to_string(), - StatusCode::BAD_REQUEST, - &return_path, - sort_param, - order_param, - theme_param, - default_color_scheme, - )); - } - } - Err(e) => { - let err = ContextualError::InvalidHTTPRequestError(e.to_string()); + let (sort_method, sort_order, _, color_scheme, path) = listing::extract_query_parameters(req); + let color_scheme = color_scheme.unwrap_or(default_color_scheme); + let upload_path = match path { + Some(path) => match path.strip_prefix(Component::RootDir) { + Ok(stripped_path) => stripped_path.to_owned(), + Err(_) => path.clone(), + }, + None => { + let err = ContextualError::InvalidHTTPRequestError( + "Missing query parameter 'path'".to_string(), + ); return Box::new(create_error_response( &err.to_string(), StatusCode::BAD_REQUEST, &return_path, - None, - None, - default_color_scheme, + sort_method, + sort_order, + color_scheme, default_color_scheme, )); } @@ -194,7 +170,7 @@ pub fn upload_file( }; // If the target path is under the app root directory, save the file. - let target_dir = match &app_root_dir.clone().join(path).canonicalize() { + let target_dir = match &app_root_dir.clone().join(upload_path).canonicalize() { Ok(path) if path.starts_with(&app_root_dir) => path.clone(), _ => { let err = ContextualError::InvalidHTTPRequestError( @@ -261,6 +237,7 @@ fn create_error_response( color_scheme, default_color_scheme, true, + true, ) .into_string(), ), -- cgit v1.2.3 From a73a74283f64986ff6a0b6da4c234a828bc52522 Mon Sep 17 00:00:00 2001 From: boastful-squirrel Date: Fri, 3 May 2019 19:32:51 +0200 Subject: Return QueryParameters struct instead of tuple --- src/file_upload.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'src/file_upload.rs') diff --git a/src/file_upload.rs b/src/file_upload.rs index 36b2401..537c90c 100644 --- a/src/file_upload.rs +++ b/src/file_upload.rs @@ -127,9 +127,9 @@ pub fn upload_file( "/".to_string() }; - let (sort_method, sort_order, _, color_scheme, path) = listing::extract_query_parameters(req); - let color_scheme = color_scheme.unwrap_or(default_color_scheme); - let upload_path = match path { + let query_params = listing::extract_query_parameters(req); + let color_scheme = query_params.theme.unwrap_or(default_color_scheme); + let upload_path = match query_params.path.clone() { Some(path) => match path.strip_prefix(Component::RootDir) { Ok(stripped_path) => stripped_path.to_owned(), Err(_) => path.clone(), @@ -142,8 +142,8 @@ pub fn upload_file( &err.to_string(), StatusCode::BAD_REQUEST, &return_path, - sort_method, - sort_order, + query_params.sort, + query_params.order, color_scheme, default_color_scheme, )); @@ -161,8 +161,8 @@ pub fn upload_file( &err.to_string(), StatusCode::INTERNAL_SERVER_ERROR, &return_path, - sort_method, - sort_order, + query_params.sort, + query_params.order, color_scheme, default_color_scheme, )); @@ -180,8 +180,8 @@ pub fn upload_file( &err.to_string(), StatusCode::BAD_REQUEST, &return_path, - sort_method, - sort_order, + query_params.sort, + query_params.order, color_scheme, default_color_scheme, )); @@ -204,8 +204,8 @@ pub fn upload_file( &e.to_string(), StatusCode::INTERNAL_SERVER_ERROR, &return_path, - sort_method, - sort_order, + query_params.sort, + query_params.order, color_scheme, default_color_scheme, ), -- cgit v1.2.3