From 63a05faebf5bd584a555e78bf69cefd67e8b253b Mon Sep 17 00:00:00 2001 From: Henning Holm Date: Sun, 3 Jan 2021 18:40:49 +0100 Subject: [PATCH] Add redirect HTTP server When using TLS/SSL, it may be desired to run an additional HTTP server that redirects all requests to the TLS/SSL version of the website as a convenience for the users. This server is disabled by default and can be enabled using the tls_redirect_from option. The HTTPS host for the redirect can be set through the tls_redirect_dest option. --- README.md | 10 ++++++++++ src/config.rs | 6 ++++++ src/main.rs | 19 +++++++++++++++++++ 3 files changed, 35 insertions(+) diff --git a/README.md b/README.md index 2091523..bb1056b 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ - First-class [Docker](https://docs.docker.com/get-started/overview/) support. [Scratch](https://hub.docker.com/_/scratch) and latest [Alpine Linux](https://hub.docker.com/_/alpine) Docker images available. - Server configurable via environment variables or CLI arguments. - MacOs binary support (`x86_64-apple-darwin`) thanks to [Rust Linux / Darwin Builder](https://github.com/joseluisq/rust-linux-darwin-builder). +- Additional HTTP redirect server for redirecting HTTP traffic to HTTPS site. ## Releases @@ -47,6 +48,8 @@ Server can be configured either via environment variables or their equivalent co | `SERVER_TLS` | Enables TLS/SSL support. Make sure also to adjust current server port. | Default `false` | | `SERVER_TLS_PKCS12` | A cryptographic identity [PKCS #12](https://docs.rs/native-tls/0.2.3/native_tls/struct.Identity.html#method.from_pkcs12) bundle file path containing a [X509 certificate](https://en.wikipedia.org/wiki/X.509) along with its corresponding private key and chain of certificates to a trusted root. | Default empty | | `SERVER_TLS_PKCS12_PASSWD` | A specified password to decrypt the private key. | Default empty | +| `SERVER_TLS_REDIRECT_FROM` | Host port for redirecting HTTP requests to HTTPS. This option enables the HTTP redirect feature | Default empty (disabled) | +| `SERVER_TLS_REDIRECT_HOST` | Host name of HTTPS site for redirecting HTTP requests to. | Default host address | | `SERVER_CORS_ALLOW_ORIGINS` | Specify a CORS list of allowed origin hosts separated by comas with no whitespaces. Host ports or protocols aren't being checked. Use an asterisk (*) to allow any host. See [Iron CORS crate](https://docs.rs/iron-cors/0.8.0/iron_cors/#mode-1-whitelist). | Default empty (which means CORS is disabled) | ### Command-line arguments @@ -92,6 +95,13 @@ OPTIONS: corresponding private key and chain of certificates to a trusted root [env: SERVER_TLS_PKCS12=] [default: ] --tls-pkcs12-passwd A specified password to decrypt the private key [env: SERVER_TLS_PKCS12_PASSWD=] [default: ] + + --tls-redirect-from + Host port for redirecting HTTP requests to HTTPS. This option enables the HTTP redirect feature [env: + SERVER_TLS_REDIRECT_FROM=] + --tls-redirect-host + Host name of HTTPS site for redirecting HTTP requests to. Defaults to host address [env: + SERVER_TLS_REDIRECT_HOST=] ``` ## TLS/SSL diff --git a/src/config.rs b/src/config.rs index 4b7448d..a3ce7b6 100644 --- a/src/config.rs +++ b/src/config.rs @@ -41,6 +41,12 @@ pub struct Options { #[structopt(long, default_value = "", env = "SERVER_TLS_PKCS12_PASSWD")] /// A specified password to decrypt the private key. pub tls_pkcs12_passwd: String, + #[structopt(long, env = "SERVER_TLS_REDIRECT_FROM")] + /// Host port for redirecting HTTP requests to HTTPS. This option enables the HTTP redirect feature. + pub tls_redirect_from: Option, + #[structopt(long, env = "SERVER_TLS_REDIRECT_HOST")] + /// Host name of HTTPS site for redirecting HTTP requests to. Defaults to host address. + pub tls_redirect_host: Option, #[structopt(long, default_value = "error", env = "SERVER_LOG_LEVEL")] /// Specify a logging level in lower case. pub log_level: String, diff --git a/src/main.rs b/src/main.rs index 751d8f5..50cfd90 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,6 +8,7 @@ extern crate log; use crate::config::Options; use hyper_native_tls::NativeTlsServer; use iron::{prelude::*, Listening}; +use iron_staticfile_middleware::HttpToHttpsRedirect; use staticfiles::*; use structopt::StructOpt; @@ -74,6 +75,24 @@ fn main() { }), Result::Err(err) => panic!("{:?}", err), } + + // Launch redirect HTTP server (if requested) + if let Some(port_redirect) = opts.tls_redirect_from { + let addr_redirect = &format!("{}{}{}", opts.host, ":", port_redirect); + let host_redirect = match opts.tls_redirect_host.as_ref() { + Some(host) => host, + None => &opts.host, + }; + let handler = + Chain::new(HttpToHttpsRedirect::new(&host_redirect, opts.port).permanent()); + match Iron::new(handler).http(addr_redirect) { + Result::Ok(listening) => running_servers.push(RunningServer { + listening, + server_type: "Redirect HTTP".to_string(), + }), + Result::Err(err) => panic!("{:?}", err), + } + } } else { // Launch static HTTP server match Iron::new(files.handle()).http(addr) { -- libgit2 1.7.2