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"
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"] }
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 }
use clap::{AppSettings, Arg, ArgMatches, Command};
+#[cfg(feature = "tls")]
use rustls::{Certificate, PrivateKey};
use std::env;
use std::net::IpAddr;
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!(
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")
.long("tls-key")
.value_name("path")
.help("Path to the SSL/TLS certificate's private key"),
- )
+ );
+
+ app
}
pub fn matches() -> ArgMatches {
pub render_spa: bool,
pub render_try_index: bool,
pub enable_cors: bool,
+ #[cfg(feature = "tls")]
pub tls: Option<(Vec<Certificate>, PrivateKey)>,
+ #[cfg(not(feature = "tls"))]
+ pub tls: Option<()>,
}
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)?;
}
_ => None,
};
+ #[cfg(not(feature = "tls"))]
+ let tls = None;
Ok(Args {
addrs,
mod logger;
mod server;
mod streamer;
+#[cfg(feature = "tls")]
mod tls;
mod utils;
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};
use hyper::server::conn::{AddrIncoming, AddrStream};
use hyper::service::{make_service_fn, service_fn};
+#[cfg(feature = "tls")]
use rustls::ServerConfig;
pub type BoxResult<T> = Result<T, Box<dyn std::error::Error>>;
}))
}
};
- 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| {
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();