index : static-web-server.git

ascending towards madness

author Henning Holm <git@henningholm.de> 2021-01-03 17:40:49.0 +00:00:00
committer Henning Holm <git@henningholm.de> 2021-01-03 17:40:49.0 +00:00:00
commit
63a05faebf5bd584a555e78bf69cefd67e8b253b [patch]
tree
382a57fb76a011f9edd78cd80c907037f302bd88
parent
baffd770729594aa65374536a01ff3511087b42c
download
63a05faebf5bd584a555e78bf69cefd67e8b253b.tar.gz

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.

Diff

 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 <tls-pkcs12-passwd>
            A specified password to decrypt the private key [env: SERVER_TLS_PKCS12_PASSWD=]  [default: ]

        --tls-redirect-from <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 <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<u16>,
    #[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<String>,
    #[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) {