diff --git a/Cargo.toml b/Cargo.toml index 35a228e..7802415 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,6 @@ keywords = ["static", "file", "server", "webdav", "cli"] clap = { version = "3", default-features = false, features = ["std", "wrap_help"] } chrono = "0.4" tokio = { version = "1", features = ["rt-multi-thread", "macros", "fs", "io-util", "signal"]} -tokio-rustls = "0.23" tokio-util = { version = "0.7", features = ["io-util"] } hyper = { version = "0.14", features = ["http1", "server", "tcp", "stream"] } percent-encoding = "2.1" @@ -27,8 +26,9 @@ async-walkdir = "0.2" headers = "0.3" mime_guess = "2.0" get_if_addrs = "0.5" -rustls = { version = "0.20", default-features = false, features = ["tls12"] } -rustls-pemfile = "1" +rustls = { version = "0.20", default-features = false, features = ["tls12"], optional = true } +rustls-pemfile = { version = "1", optional = true } +tokio-rustls = { version = "0.23", optional = true } md5 = "0.7" lazy_static = "1.4" uuid = { version = "1.1", features = ["v4", "fast-rng"] } @@ -38,6 +38,10 @@ log = "0.4" socket2 = "0.4" async-stream = "0.3" +[features] +default = ["tls"] +tls = ["rustls", "rustls-pemfile", "tokio-rustls"] + [dev-dependencies] assert_cmd = "2" reqwest = { version = "0.11", features = ["blocking", "multipart", "rustls-tls"], default-features = false } diff --git a/src/args.rs b/src/args.rs index f072217..11fbfe1 100644 --- a/src/args.rs +++ b/src/args.rs @@ -1,4 +1,5 @@ use clap::{AppSettings, Arg, ArgMatches, Command}; +#[cfg(feature = "tls")] use rustls::{Certificate, PrivateKey}; use std::env; use std::net::IpAddr; @@ -6,11 +7,12 @@ use std::path::{Path, PathBuf}; use crate::auth::AccessControl; use crate::auth::AuthMethod; +#[cfg(feature = "tls")] use crate::tls::{load_certs, load_private_key}; use crate::BoxResult; fn app() -> Command<'static> { - Command::new(env!("CARGO_CRATE_NAME")) + let app = Command::new(env!("CARGO_CRATE_NAME")) .version(env!("CARGO_PKG_VERSION")) .author(env!("CARGO_PKG_AUTHORS")) .about(concat!( @@ -116,7 +118,10 @@ fn app() -> Command<'static> { Arg::new("render-spa") .long("render-spa") .help("Serve SPA(Single Page Application)"), - ) + ); + + #[cfg(feature = "tls")] + let app = app .arg( Arg::new("tls-cert") .long("tls-cert") @@ -128,7 +133,9 @@ fn app() -> Command<'static> { .long("tls-key") .value_name("path") .help("Path to the SSL/TLS certificate's private key"), - ) + ); + + app } pub fn matches() -> ArgMatches { @@ -154,7 +161,10 @@ pub struct Args { pub render_spa: bool, pub render_try_index: bool, pub enable_cors: bool, + #[cfg(feature = "tls")] pub tls: Option<(Vec, PrivateKey)>, + #[cfg(not(feature = "tls"))] + pub tls: Option<()>, } impl Args { @@ -201,6 +211,7 @@ impl Args { let render_index = matches.is_present("render-index"); let render_try_index = matches.is_present("render-try-index"); let render_spa = matches.is_present("render-spa"); + #[cfg(feature = "tls")] let tls = match (matches.value_of("tls-cert"), matches.value_of("tls-key")) { (Some(certs_file), Some(key_file)) => { let certs = load_certs(certs_file)?; @@ -209,6 +220,8 @@ impl Args { } _ => None, }; + #[cfg(not(feature = "tls"))] + let tls = None; Ok(Args { addrs, diff --git a/src/main.rs b/src/main.rs index bf579f0..7fbecd4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,6 +3,7 @@ mod auth; mod logger; mod server; mod streamer; +#[cfg(feature = "tls")] mod tls; mod utils; @@ -11,6 +12,7 @@ extern crate log; use crate::args::{matches, Args}; use crate::server::{Request, Server}; +#[cfg(feature = "tls")] use crate::tls::{TlsAcceptor, TlsStream}; use std::net::{IpAddr, SocketAddr, TcpListener as StdTcpListener}; @@ -22,6 +24,7 @@ use tokio::task::JoinHandle; use hyper::server::conn::{AddrIncoming, AddrStream}; use hyper::service::{make_service_fn, service_fn}; +#[cfg(feature = "tls")] use rustls::ServerConfig; pub type BoxResult = Result>; @@ -70,12 +73,13 @@ fn serve(args: Arc) -> BoxResult>> })) } }; - match args.tls.clone() { + match args.tls.as_ref() { + #[cfg(feature = "tls")] Some((certs, key)) => { let config = ServerConfig::builder() .with_safe_defaults() .with_no_client_auth() - .with_single_cert(certs, key)?; + .with_single_cert(certs.clone(), key.clone())?; let config = Arc::new(config); let accepter = TlsAcceptor::new(config.clone(), incoming); let new_service = make_service_fn(move |socket: &TlsStream| { @@ -85,6 +89,10 @@ fn serve(args: Arc) -> BoxResult>> let server = tokio::spawn(hyper::Server::builder(accepter).serve(new_service)); handles.push(server); } + #[cfg(not(feature = "tls"))] + Some(_) => { + unreachable!() + } None => { let new_service = make_service_fn(move |socket: &AddrStream| { let remote_addr = socket.remote_addr();