aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/archive.rs38
-rw-r--r--src/args.rs14
-rw-r--r--src/auth.rs12
-rw-r--r--src/errors.rs58
-rw-r--r--src/file_upload.rs32
-rw-r--r--src/main.rs26
6 files changed, 62 insertions, 118 deletions
diff --git a/src/archive.rs b/src/archive.rs
index b5788f5..a76446a 100644
--- a/src/archive.rs
+++ b/src/archive.rs
@@ -7,7 +7,7 @@ use std::path::PathBuf;
use strum_macros::{Display, EnumIter, EnumString};
use tar::Builder;
-use crate::errors::{ContextualError, ContextualErrorKind};
+use crate::errors::{ContextualError};
/// Available compression methods
#[derive(Deserialize, Clone, EnumIter, EnumString, Display)]
@@ -62,17 +62,17 @@ fn tgz_compress(dir: &PathBuf, skip_symlinks: bool) -> Result<(String, Bytes), C
let mut tgz_data = Bytes::new();
let tar_data = tar(src_dir, directory.to_string(), skip_symlinks).map_err(|e| {
- ContextualError::new(ContextualErrorKind::ArchiveCreationError(
+ ContextualError::ArchiveCreationError(
"tarball".to_string(),
Box::new(e),
- ))
+ )
})?;
let gz_data = gzip(&tar_data).map_err(|e| {
- ContextualError::new(ContextualErrorKind::ArchiveCreationError(
+ ContextualError::ArchiveCreationError(
"GZIP archive".to_string(),
Box::new(e),
- ))
+ )
})?;
tgz_data.extend_from_slice(&gz_data);
@@ -80,15 +80,15 @@ fn tgz_compress(dir: &PathBuf, skip_symlinks: bool) -> Result<(String, Bytes), C
Ok((dst_tgz_filename, tgz_data))
} else {
// https://doc.rust-lang.org/std/ffi/struct.OsStr.html#method.to_str
- Err(ContextualError::new(ContextualErrorKind::InvalidPathError(
+ Err(ContextualError::InvalidPathError(
"Directory name contains invalid UTF-8 characters".to_string(),
- )))
+ ))
}
} else {
// https://doc.rust-lang.org/std/path/struct.Path.html#method.file_name
- Err(ContextualError::new(ContextualErrorKind::InvalidPathError(
+ Err(ContextualError::InvalidPathError(
"Directory name terminates in \"..\"".to_string(),
- )))
+ ))
}
}
@@ -105,20 +105,20 @@ fn tar(
tar_builder
.append_dir_all(inner_folder, &src_dir)
.map_err(|e| {
- ContextualError::new(ContextualErrorKind::IOError(
+ ContextualError::IOError(
format!(
"Failed to append the content of {} to the TAR archive",
&src_dir
),
e,
- ))
+ )
})?;
let tar_content = tar_builder.into_inner().map_err(|e| {
- ContextualError::new(ContextualErrorKind::IOError(
+ ContextualError::IOError(
"Failed to finish writing the TAR archive".to_string(),
e,
- ))
+ )
})?;
Ok(tar_content)
@@ -127,22 +127,22 @@ fn tar(
/// Compresses a stream of bytes using the GZIP algorithm, and returns the resulting stream
fn gzip(mut data: &[u8]) -> Result<Vec<u8>, ContextualError> {
let mut encoder = Encoder::new(Vec::new()).map_err(|e| {
- ContextualError::new(ContextualErrorKind::IOError(
+ ContextualError::IOError(
"Failed to create GZIP encoder".to_string(),
e,
- ))
+ )
})?;
io::copy(&mut data, &mut encoder).map_err(|e| {
- ContextualError::new(ContextualErrorKind::IOError(
+ ContextualError::IOError(
"Failed to write GZIP data".to_string(),
e,
- ))
+ )
})?;
let data = encoder.finish().into_result().map_err(|e| {
- ContextualError::new(ContextualErrorKind::IOError(
+ ContextualError::IOError(
"Failed to write GZIP trailer".to_string(),
e,
- ))
+ )
})?;
Ok(data)
diff --git a/src/args.rs b/src/args.rs
index 4077f35..63799a0 100644
--- a/src/args.rs
+++ b/src/args.rs
@@ -3,7 +3,7 @@ use std::path::PathBuf;
use structopt::StructOpt;
use crate::auth;
-use crate::errors::{ContextualError, ContextualErrorKind};
+use crate::errors::{ContextualError};
use crate::themes;
/// Possible characters for random routes
@@ -80,9 +80,7 @@ fn parse_interface(src: &str) -> Result<IpAddr, std::net::AddrParseError> {
/// Checks wether the auth string is valid, i.e. it follows the syntax username:password
fn parse_auth(src: &str) -> Result<auth::RequiredAuth, ContextualError> {
let mut split = src.splitn(3, ':');
- let invalid_auth_format = Err(
- ContextualError::new(ContextualErrorKind::InvalidAuthFormat)
- );
+ let invalid_auth_format = Err(ContextualError::InvalidAuthFormat);
let username = match split.next() {
Some(username) => username,
@@ -100,16 +98,14 @@ fn parse_auth(src: &str) -> Result<auth::RequiredAuth, ContextualError> {
let hash_bin = if let Ok(hash_bin) = hex::decode(hash_hex) {
hash_bin
} else {
- return Err(ContextualError::new(ContextualErrorKind::InvalidPasswordHash))
+ return Err(ContextualError::InvalidPasswordHash)
};
match second_part {
"sha256" => auth::RequiredAuthPassword::Sha256(hash_bin.to_owned()),
"sha512" => auth::RequiredAuthPassword::Sha512(hash_bin.to_owned()),
_ => {
- return Err(ContextualError::new(
- ContextualErrorKind::InvalidHashMethod(second_part.to_owned())
- ))
+ return Err(ContextualError::InvalidHashMethod(second_part.to_owned()))
},
}
} else {
@@ -117,7 +113,7 @@ fn parse_auth(src: &str) -> Result<auth::RequiredAuth, ContextualError> {
// After 255 characters, Windows will truncate the value.
// As for the username, the spec does not mention a limit in length
if second_part.len() > 255 {
- return Err(ContextualError::new(ContextualErrorKind::PasswordTooLongError));
+ return Err(ContextualError::PasswordTooLongError);
}
auth::RequiredAuthPassword::Plain(second_part.to_owned())
diff --git a/src/auth.rs b/src/auth.rs
index e75f498..8e6532b 100644
--- a/src/auth.rs
+++ b/src/auth.rs
@@ -3,7 +3,7 @@ use actix_web::middleware::{Middleware, Response};
use actix_web::{HttpRequest, HttpResponse, Result};
use sha2::{Digest, Sha256, Sha512};
-use crate::errors::{ContextualError, ContextualErrorKind};
+use crate::errors::{ContextualError};
pub struct Auth;
@@ -36,13 +36,13 @@ pub fn parse_basic_auth(
let basic_removed = authorization_header
.to_str()
.map_err(|e| {
- ContextualError::new(ContextualErrorKind::ParseError(
+ ContextualError::ParseError(
"HTTP authentication header".to_string(),
e.to_string(),
- ))
+ )
})?
.replace("Basic ", "");
- let decoded = base64::decode(&basic_removed).map_err(ContextualErrorKind::Base64DecodeError)?;
+ let decoded = base64::decode(&basic_removed).map_err(ContextualError::Base64DecodeError)?;
let decoded_str = String::from_utf8_lossy(&decoded);
let credentials: Vec<&str> = decoded_str.splitn(2, ':').collect();
@@ -97,9 +97,7 @@ impl Middleware<crate::MiniserveConfig> for Auth {
let auth_req = match parse_basic_auth(auth_headers) {
Ok(auth_req) => auth_req,
Err(err) => {
- let auth_err = ContextualError::new(
- ContextualErrorKind::HTTPAuthenticationError(Box::new(err)),
- );
+ let auth_err = ContextualError::HTTPAuthenticationError(Box::new(err));
return Ok(Response::Done(
HttpResponse::BadRequest().body(auth_err.to_string()),
));
diff --git a/src/errors.rs b/src/errors.rs
index 833e9c4..b8af25d 100644
--- a/src/errors.rs
+++ b/src/errors.rs
@@ -1,8 +1,7 @@
-use failure::{Backtrace, Context, Fail};
-use std::fmt::{self, Debug, Display};
+use failure::Fail;
#[derive(Debug, Fail)]
-pub enum ContextualErrorKind {
+pub enum ContextualError {
/// Fully customized errors, not inheriting from any error
#[fail(display = "{}", _0)]
CustomError(String),
@@ -73,58 +72,9 @@ pub fn log_error_chain(description: String) {
}
}
-/// Based on https://boats.gitlab.io/failure/error-errorkind.html
-pub struct ContextualError {
- inner: Context<ContextualErrorKind>,
-}
-
-impl ContextualError {
- pub fn new(kind: ContextualErrorKind) -> ContextualError {
- ContextualError {
- inner: Context::new(kind),
- }
- }
-}
-
-impl Fail for ContextualError {
- fn cause(&self) -> Option<&Fail> {
- self.inner.cause()
- }
-
- fn backtrace(&self) -> Option<&Backtrace> {
- self.inner.backtrace()
- }
-}
-
-impl Display for ContextualError {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- Display::fmt(&self.inner, f)
- }
-}
-
-impl Debug for ContextualError {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- Debug::fmt(&self.inner, f)
- }
-}
-
-impl From<Context<ContextualErrorKind>> for ContextualError {
- fn from(inner: Context<ContextualErrorKind>) -> ContextualError {
- ContextualError { inner }
- }
-}
-
-impl From<ContextualErrorKind> for ContextualError {
- fn from(kind: ContextualErrorKind) -> ContextualError {
- ContextualError {
- inner: Context::new(kind),
- }
- }
-}
-
-/// This allows to create CustomErrors more simply
+/// This makes creating CustomErrors easier
impl From<String> for ContextualError {
fn from(msg: String) -> ContextualError {
- ContextualError::new(ContextualErrorKind::CustomError(msg))
+ ContextualError::CustomError(msg)
}
}
diff --git a/src/file_upload.rs b/src/file_upload.rs
index 1618617..7f9cede 100644
--- a/src/file_upload.rs
+++ b/src/file_upload.rs
@@ -10,7 +10,7 @@ use std::{
path::{Component, PathBuf},
};
-use crate::errors::{self, ContextualErrorKind};
+use crate::errors::{self, ContextualError};
use crate::renderer;
/// Query parameters
@@ -24,9 +24,9 @@ fn save_file(
field: multipart::Field<dev::Payload>,
file_path: PathBuf,
overwrite_files: bool,
-) -> Box<Future<Item = i64, Error = ContextualErrorKind>> {
+) -> Box<Future<Item = i64, Error = ContextualError>> {
if !overwrite_files && file_path.exists() {
- return Box::new(future::err(ContextualErrorKind::CustomError(
+ return Box::new(future::err(ContextualError::CustomError(
"File already exists, and the overwrite_files option has not been set".to_string(),
)));
}
@@ -34,7 +34,7 @@ fn save_file(
let mut file = match std::fs::File::create(&file_path) {
Ok(file) => file,
Err(e) => {
- return Box::new(future::err(ContextualErrorKind::IOError(
+ return Box::new(future::err(ContextualError::IOError(
format!("Failed to create file in {}", file_path.display()),
e,
)));
@@ -42,13 +42,13 @@ fn save_file(
};
Box::new(
field
- .map_err(ContextualErrorKind::MultipartError)
+ .map_err(ContextualError::MultipartError)
.fold(0i64, move |acc, bytes| {
let rt = file
.write_all(bytes.as_ref())
.map(|_| acc + bytes.len() as i64)
.map_err(|e| {
- ContextualErrorKind::IOError("Failed to write to file".to_string(), e)
+ ContextualError::IOError("Failed to write to file".to_string(), e)
});
future::result(rt)
}),
@@ -60,41 +60,41 @@ fn handle_multipart(
item: multipart::MultipartItem<dev::Payload>,
mut file_path: PathBuf,
overwrite_files: bool,
-) -> Box<Stream<Item = i64, Error = ContextualErrorKind>> {
+) -> Box<Stream<Item = i64, Error = ContextualError>> {
match item {
multipart::MultipartItem::Field(field) => {
let filename = field
.headers()
.get(header::CONTENT_DISPOSITION)
- .ok_or(ContextualErrorKind::ParseError)
+ .ok_or(ContextualError::ParseError)
.and_then(|cd| {
header::ContentDisposition::from_raw(cd)
- .map_err(|_| ContextualErrorKind::ParseError)
+ .map_err(|_| ContextualError::ParseError)
})
.and_then(|content_disposition| {
content_disposition
.get_filename()
- .ok_or(ContextualErrorKind::ParseError)
+ .ok_or(ContextualError::ParseError)
.map(String::from)
});
- let err = |e: ContextualErrorKind| Box::new(future::err(e).into_stream());
+ let err = |e: ContextualError| Box::new(future::err(e).into_stream());
match filename {
Ok(f) => {
match fs::metadata(&file_path) {
Ok(metadata) => {
if !metadata.is_dir() {
- return err(ContextualErrorKind::InvalidPathError(format!(
+ return err(ContextualError::InvalidPathError(format!(
"cannot upload file to {}, since it's not a directory",
&file_path.display()
)));
} else if metadata.permissions().readonly() {
- return err(ContextualErrorKind::InsufficientPermissionsError(
+ return err(ContextualError::InsufficientPermissionsError(
file_path.display().to_string(),
));
}
}
Err(_) => {
- return err(ContextualErrorKind::InsufficientPermissionsError(
+ return err(ContextualError::InsufficientPermissionsError(
file_path.display().to_string(),
));
}
@@ -109,7 +109,7 @@ fn handle_multipart(
}
}
multipart::MultipartItem::Nested(mp) => Box::new(
- mp.map_err(ContextualErrorKind::MultipartError)
+ mp.map_err(ContextualError::MultipartError)
.map(move |item| handle_multipart(item, file_path.clone(), overwrite_files))
.flatten(),
),
@@ -156,7 +156,7 @@ pub fn upload_file(req: &HttpRequest<crate::MiniserveConfig>) -> FutureResponse<
let overwrite_files = req.state().overwrite_files;
Box::new(
req.multipart()
- .map_err(ContextualErrorKind::MultipartError)
+ .map_err(ContextualError::MultipartError)
.map(move |item| handle_multipart(item, target_dir.clone(), overwrite_files))
.flatten()
.collect()
diff --git a/src/main.rs b/src/main.rs
index bc8f3f0..c1bb0aa 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -19,7 +19,7 @@ mod listing;
mod renderer;
mod themes;
-use crate::errors::{ContextualError, ContextualErrorKind};
+use crate::errors::{ContextualError};
#[derive(Clone)]
/// Configuration of the Miniserve application
@@ -84,10 +84,10 @@ fn run() -> Result<(), ContextualError> {
.path
.symlink_metadata()
.map_err(|e| {
- ContextualError::new(ContextualErrorKind::IOError(
+ ContextualError::IOError(
"Failed to retrieve symlink's metadata".to_string(),
e,
- ))
+ )
})?
.file_type()
.is_symlink()
@@ -117,10 +117,10 @@ fn run() -> Result<(), ContextualError> {
.collect::<Vec<String>>();
let canon_path = miniserve_config.path.canonicalize().map_err(|e| {
- ContextualError::new(ContextualErrorKind::IOError(
+ ContextualError::IOError(
"Failed to resolve path to be served".to_string(),
e,
- ))
+ )
})?;
let path_string = canon_path.to_string_lossy();
@@ -136,18 +136,18 @@ fn run() -> Result<(), ContextualError> {
);
print!("Starting server in ");
io::stdout().flush().map_err(|e| {
- ContextualError::new(ContextualErrorKind::IOError(
+ ContextualError::IOError(
"Failed to write data".to_string(),
e,
- ))
+ )
})?;
for c in "3… 2… 1… \n".chars() {
print!("{}", c);
io::stdout().flush().map_err(|e| {
- ContextualError::new(ContextualErrorKind::IOError(
+ ContextualError::IOError(
"Failed to write data".to_string(),
e,
- ))
+ )
})?;
thread::sleep(Duration::from_millis(500));
}
@@ -196,10 +196,10 @@ fn run() -> Result<(), ContextualError> {
// Note that this should never fail, since CLI parsing succeeded
// This means the format of each IP address is valid, and so is the port
// Valid IpAddr + valid port == valid SocketAddr
- return Err(ContextualError::new(ContextualErrorKind::ParseError(
+ return Err(ContextualError::ParseError(
"string as socket address".to_string(),
e.to_string(),
- )));
+ ));
}
};
@@ -211,10 +211,10 @@ fn run() -> Result<(), ContextualError> {
})
.bind(socket_addresses.as_slice())
.map_err(|e| {
- ContextualError::new(ContextualErrorKind::IOError(
+ ContextualError::IOError(
"Failed to bind server".to_string(),
e,
- ))
+ )
})?
.shutdown_timeout(0)
.start();