diff options
author | khai96_ <hvksmr1996@gmail.com> | 2019-04-26 06:04:16 +0000 |
---|---|---|
committer | khai96_ <hvksmr1996@gmail.com> | 2019-04-26 06:04:16 +0000 |
commit | 838d86655fb39b5cdf63b2d3823ce047e63afaf4 (patch) | |
tree | cf5306f1050108f872d6d7d020606f5dc5c90206 /src/main.rs | |
parent | Use rstest_parametrize for unit tests (diff) | |
parent | Use rstest test fixtures to cut down on code duplication in integration tests (diff) | |
download | miniserve-838d86655fb39b5cdf63b2d3823ce047e63afaf4.tar.gz miniserve-838d86655fb39b5cdf63b2d3823ce047e63afaf4.zip |
Merge remote-tracking branch 'mainrepo/master' into pullrequest.hashed-password
Diffstat (limited to 'src/main.rs')
-rw-r--r-- | src/main.rs | 87 |
1 files changed, 67 insertions, 20 deletions
diff --git a/src/main.rs b/src/main.rs index e63b505..bc8f3f0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,6 +19,8 @@ mod listing; mod renderer; mod themes; +use crate::errors::{ContextualError, ContextualErrorKind}; + #[derive(Clone)] /// Configuration of the Miniserve application pub struct MiniserveConfig { @@ -57,10 +59,18 @@ pub struct MiniserveConfig { } fn main() { + match run() { + Ok(()) => (), + Err(e) => errors::log_error_chain(e.to_string()), + } +} + +fn run() -> Result<(), ContextualError> { if cfg!(windows) && !Paint::enable_windows_ascii() { Paint::disable(); } + let sys = actix::System::new("miniserve"); let miniserve_config = args::parse_args(); let _ = if miniserve_config.verbose { @@ -73,16 +83,20 @@ fn main() { && miniserve_config .path .symlink_metadata() - .expect("Can't get file metadata") + .map_err(|e| { + ContextualError::new(ContextualErrorKind::IOError( + "Failed to retrieve symlink's metadata".to_string(), + e, + )) + })? .file_type() .is_symlink() { - log::error!("The no-symlinks option cannot be used with a symlink path"); - return; + return Err(ContextualError::from( + "The no-symlinks option cannot be used with a symlink path".to_string(), + )); } - let sys = actix::System::new("miniserve"); - let inside_config = miniserve_config.clone(); let interfaces = miniserve_config @@ -102,7 +116,12 @@ fn main() { }) .collect::<Vec<String>>(); - let canon_path = miniserve_config.path.canonicalize().unwrap(); + let canon_path = miniserve_config.path.canonicalize().map_err(|e| { + ContextualError::new(ContextualErrorKind::IOError( + "Failed to resolve path to be served".to_string(), + e, + )) + })?; let path_string = canon_path.to_string_lossy(); println!( @@ -116,10 +135,20 @@ fn main() { " Invoke with -h|--help to see options or invoke as `miniserve .` to hide this advice." ); print!("Starting server in "); - io::stdout().flush().unwrap(); + io::stdout().flush().map_err(|e| { + ContextualError::new(ContextualErrorKind::IOError( + "Failed to write data".to_string(), + e, + )) + })?; for c in "3… 2… 1… \n".chars() { print!("{}", c); - io::stdout().flush().unwrap(); + io::stdout().flush().map_err(|e| { + ContextualError::new(ContextualErrorKind::IOError( + "Failed to write data".to_string(), + e, + )) + })?; thread::sleep(Duration::from_millis(500)); } } @@ -148,12 +177,6 @@ fn main() { )); } } - println!( - "Serving path {path} at {addresses}", - path = Color::Yellow.paint(path_string).bold(), - addresses = addresses, - ); - println!("\nQuit by pressing CTRL-C"); let socket_addresses = interfaces .iter() @@ -167,10 +190,18 @@ fn main() { }) .collect::<Result<Vec<SocketAddr>, _>>(); - // 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 - let socket_addresses = socket_addresses.expect("Failed to parse string as socket address"); + let socket_addresses = match socket_addresses { + Ok(addresses) => addresses, + Err(e) => { + // 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( + "string as socket address".to_string(), + e.to_string(), + ))); + } + }; server::new(move || { App::with_state(inside_config.clone()) @@ -179,10 +210,26 @@ fn main() { .configure(configure_app) }) .bind(socket_addresses.as_slice()) - .expect("Couldn't bind server") + .map_err(|e| { + ContextualError::new(ContextualErrorKind::IOError( + "Failed to bind server".to_string(), + e, + )) + })? .shutdown_timeout(0) .start(); + + println!( + "Serving path {path} at {addresses}", + path = Color::Yellow.paint(path_string).bold(), + addresses = addresses, + ); + + println!("\nQuit by pressing CTRL-C"); + let _ = sys.run(); + + Ok(()) } /// Configures the Actix application @@ -205,7 +252,7 @@ fn configure_app(app: App<MiniserveConfig>) -> App<MiniserveConfig> { let u_r = upload_route.clone(); Some( fs::StaticFiles::new(path) - .expect("Couldn't create path") + .expect("Failed to setup static file handler") .show_files_listing() .files_listing_renderer(move |dir, req| { listing::directory_listing( |