aboutsummaryrefslogtreecommitdiffstats
path: root/src/file_upload.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/file_upload.rs')
-rw-r--r--src/file_upload.rs123
1 files changed, 99 insertions, 24 deletions
diff --git a/src/file_upload.rs b/src/file_upload.rs
index 7f9cede..46a3a1f 100644
--- a/src/file_upload.rs
+++ b/src/file_upload.rs
@@ -3,7 +3,6 @@ use actix_web::{
HttpResponse, Query,
};
use futures::{future, future::FutureResult, Future, Stream};
-use serde::Deserialize;
use std::{
fs,
io::Write,
@@ -11,13 +10,9 @@ use std::{
};
use crate::errors::{self, ContextualError};
+use crate::listing::{QueryParameters, SortingMethod, SortingOrder};
use crate::renderer;
-
-/// Query parameters
-#[derive(Debug, Deserialize)]
-struct QueryParameters {
- path: PathBuf,
-}
+use crate::themes::ColorScheme;
/// Create future to save file.
fn save_file(
@@ -35,7 +30,7 @@ fn save_file(
Ok(file) => file,
Err(e) => {
return Box::new(future::err(ContextualError::IOError(
- format!("Failed to create file in {}", file_path.display()),
+ format!("Failed to create {}", file_path.display()),
e,
)));
}
@@ -121,37 +116,95 @@ 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<crate::MiniserveConfig>) -> FutureResponse<HttpResponse> {
+pub fn upload_file(
+ req: &HttpRequest<crate::MiniserveConfig>,
+ default_color_scheme: ColorScheme,
+) -> FutureResponse<HttpResponse> {
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 = if let Ok(dir) = req.state().path.canonicalize() {
- dir
- } else {
- return Box::new(create_error_response("Internal server error", &return_path));
- };
- let path = match Query::<QueryParameters>::extract(req) {
+
+ let (path, sort_method, sort_order, color_scheme) = match Query::<QueryParameters>::extract(req)
+ {
Ok(query) => {
- if let Ok(stripped_path) = query.path.strip_prefix(Component::RootDir) {
- stripped_path.to_owned()
+ 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 {
- query.path.clone()
+ let err = ContextualError::InvalidHTTPRequestError(
+ "Missing query parameter 'path'".to_string(),
+ );
+ return Box::new(create_error_response(
+ &err.to_string(),
+ &return_path,
+ sort_param,
+ order_param,
+ theme_param,
+ default_color_scheme,
+ ));
}
}
- Err(_) => {
+ Err(e) => {
+ let err = ContextualError::InvalidHTTPRequestError(e.to_string());
return Box::new(create_error_response(
- "Unspecified parameter path",
+ &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::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,
+ ));
}
};
// 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::InvalidHTTPRequestError(
+ "Invalid value for 'path' parameter".to_string(),
+ );
+ 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;
Box::new(
@@ -166,7 +219,14 @@ pub fn upload_file(req: &HttpRequest<crate::MiniserveConfig>) -> 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,
+ ),
}),
)
}
@@ -175,11 +235,26 @@ pub fn upload_file(req: &HttpRequest<crate::MiniserveConfig>) -> FutureResponse<
fn create_error_response(
description: &str,
return_path: &str,
+ sorting_method: Option<SortingMethod>,
+ sorting_order: Option<SortingOrder>,
+ color_scheme: ColorScheme,
+ default_color_scheme: ColorScheme,
) -> FutureResult<HttpResponse, actix_web::error::Error> {
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(),
+ ),
)
}