From 8ba2eff7efbd2160d79bede1b05674954c640d68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojt=C4=9Bch=20Pej=C5=A1a?= Date: Sun, 7 Apr 2019 18:53:54 +0200 Subject: Fix timeout error when uploading takes longer. --- src/file_upload.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/file_upload.rs') diff --git a/src/file_upload.rs b/src/file_upload.rs index 273d12c..79ed7b1 100644 --- a/src/file_upload.rs +++ b/src/file_upload.rs @@ -1,8 +1,9 @@ use crate::errors::FileUploadErrorKind; use crate::renderer::file_upload_error; use actix_web::{ - dev, http::header, multipart, FromRequest, FutureResponse, HttpMessage, HttpRequest, - HttpResponse, Query, + dev, + http::{header, StatusCode}, + multipart, FromRequest, FutureResponse, HttpMessage, HttpRequest, HttpResponse, Query, }; use futures::{future, Future, Stream}; use serde::Deserialize; @@ -138,6 +139,7 @@ pub fn upload_file(req: &HttpRequest) -> FutureResponse< .collect() .map(move |_| { HttpResponse::TemporaryRedirect() + .status(StatusCode::SEE_OTHER) .header(header::LOCATION, return_path.to_string()) .finish() }) -- cgit v1.2.3 From 32d9391f9b8846c6216716ac48f60a35bd884fa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojt=C4=9Bch=20Pej=C5=A1a?= Date: Tue, 9 Apr 2019 00:23:58 +0200 Subject: Refactor file upload. --- src/file_upload.rs | 66 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 28 deletions(-) (limited to 'src/file_upload.rs') diff --git a/src/file_upload.rs b/src/file_upload.rs index 79ed7b1..5ef793d 100644 --- a/src/file_upload.rs +++ b/src/file_upload.rs @@ -1,11 +1,10 @@ use crate::errors::FileUploadErrorKind; use crate::renderer::file_upload_error; use actix_web::{ - dev, - http::{header, StatusCode}, - multipart, FromRequest, FutureResponse, HttpMessage, HttpRequest, HttpResponse, Query, + dev, http::header, multipart, FromRequest, FutureResponse, HttpMessage, HttpRequest, + HttpResponse, Query, }; -use futures::{future, Future, Stream}; +use futures::{future, future::FutureResult, Future, Stream}; use serde::Deserialize; use std::{ fs, @@ -102,7 +101,14 @@ fn handle_multipart( /// invalid. /// This method returns future. pub fn upload_file(req: &HttpRequest) -> FutureResponse { - let app_root_dir = req.state().path.clone().canonicalize().unwrap(); + let return_path: String = req.headers()[header::REFERER] + .to_str() + .unwrap_or("/") + .to_owned(); + let app_root_dir = match req.state().path.canonicalize() { + Ok(path) => path, + Err(_) => return Box::new(create_error_response("Internal server error", &return_path)), + }; let path = match Query::::extract(req) { Ok(query) => { if let Ok(stripped_path) = query.path.strip_prefix(Component::RootDir) { @@ -112,23 +118,17 @@ pub fn upload_file(req: &HttpRequest) -> FutureResponse< } } Err(_) => { - return Box::new(future::ok( - HttpResponse::BadRequest().body("Unspecified parameter path"), + return Box::new(create_error_response( + "Unspecified parameter path", + &return_path, )) } }; - // this is really ugly I will try to think about something smarter - let return_path: String = req.headers()[header::REFERER] - .clone() - .to_str() - .unwrap_or("/") - .to_owned(); - let r_p2 = return_path.clone(); // If the target path is under the app root directory, save the file. - let target_dir = match &app_root_dir.clone().join(path.clone()).canonicalize() { + 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(future::ok(HttpResponse::BadRequest().body("Invalid path"))), + _ => return Box::new(create_error_response("Invalid path", &return_path)), }; let overwrite_files = req.state().overwrite_files; Box::new( @@ -137,18 +137,28 @@ pub fn upload_file(req: &HttpRequest) -> FutureResponse< .map(move |item| handle_multipart(item, target_dir.clone(), overwrite_files)) .flatten() .collect() - .map(move |_| { - HttpResponse::TemporaryRedirect() - .status(StatusCode::SEE_OTHER) - .header(header::LOCATION, return_path.to_string()) - .finish() - }) - .or_else(move |e| { - let error_description = format!("{}", e); - future::ok( - HttpResponse::BadRequest() - .body(file_upload_error(&error_description, &r_p2.clone()).into_string()), - ) + .then(move |e| match e { + Ok(_) => future::ok( + HttpResponse::SeeOther() + .header(header::LOCATION, return_path.to_string()) + .finish(), + ), + Err(e) => { + let error_description = format!("{}", e); + create_error_response(&error_description, &return_path) + } }), ) } + +// Convenience method for creating response errors, when file upload fails. +fn create_error_response( + description: &str, + return_path: &str, +) -> FutureResult { + future::ok( + HttpResponse::NotAcceptable() + .content_type("text/html; charset=utf-8") + .body(file_upload_error(description, return_path).into_string()), + ) +} -- cgit v1.2.3 From 786a0e3e079469b0d57d7d870ec6dbfd6b921f7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojt=C4=9Bch=20Pej=C5=A1a?= Date: Tue, 9 Apr 2019 20:57:57 +0200 Subject: Change HTTP response code and cleanup previus commit. --- src/file_upload.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src/file_upload.rs') diff --git a/src/file_upload.rs b/src/file_upload.rs index 5ef793d..4a0ae1f 100644 --- a/src/file_upload.rs +++ b/src/file_upload.rs @@ -105,9 +105,10 @@ pub fn upload_file(req: &HttpRequest) -> FutureResponse< .to_str() .unwrap_or("/") .to_owned(); - let app_root_dir = match req.state().path.canonicalize() { - Ok(path) => path, - Err(_) => return Box::new(create_error_response("Internal server error", &return_path)), + 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::::extract(req) { Ok(query) => { @@ -151,13 +152,13 @@ pub fn upload_file(req: &HttpRequest) -> FutureResponse< ) } -// Convenience method for creating response errors, when file upload fails. +/// Convenience method for creating response errors, if file upload fails. fn create_error_response( description: &str, return_path: &str, ) -> FutureResult { future::ok( - HttpResponse::NotAcceptable() + HttpResponse::BadRequest() .content_type("text/html; charset=utf-8") .body(file_upload_error(description, return_path).into_string()), ) -- cgit v1.2.3 From d3e0c18a4258b89c70e23205645c6dda61f90af0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojt=C4=9Bch=20Pej=C5=A1a?= Date: Tue, 9 Apr 2019 22:08:14 +0200 Subject: Replace format with to_string() --- src/file_upload.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src/file_upload.rs') diff --git a/src/file_upload.rs b/src/file_upload.rs index 4a0ae1f..534083c 100644 --- a/src/file_upload.rs +++ b/src/file_upload.rs @@ -144,10 +144,7 @@ pub fn upload_file(req: &HttpRequest) -> FutureResponse< .header(header::LOCATION, return_path.to_string()) .finish(), ), - Err(e) => { - let error_description = format!("{}", e); - create_error_response(&error_description, &return_path) - } + Err(e) => create_error_response(&e.to_string(), &return_path), }), ) } -- cgit v1.2.3