index : static-web-server.git

ascending towards madness

author Jose Quintana <joseluisquintana20@gmail.com> 2021-01-25 15:35:15.0 +00:00:00
committer Jose Quintana <joseluisquintana20@gmail.com> 2021-01-25 15:35:15.0 +00:00:00
commit
4667b10c0a720f996110060fa456f491635b87d2 [patch]
tree
648d858af3dd9cda8de69e32faba6100aac4d2fb
parent
bff49a0adcf7e68159d5b2eaeb7504f02a0ed0ca
download
4667b10c0a720f996110060fa456f491635b87d2.tar.gz

feat: http/2 + tls support



Diff

 Cargo.lock    | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 Cargo.toml    |   2 +-
 src/config.rs |  12 +++++-
 src/server.rs | 129 ++++++++++++++++++++++++++++++++++++++------------
 4 files changed, 263 insertions(+), 31 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 67707c0..ec68c17 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -171,6 +171,12 @@ dependencies = [
]

[[package]]
name = "bumpalo"
version = "3.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f07aa6688c702439a1be0307b6a94dffe1168569e45b9500c1372bc580740d59"

[[package]]
name = "byte-tools"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -597,6 +603,15 @@ dependencies = [
]

[[package]]
name = "js-sys"
version = "0.3.46"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf3d7383929f7c9c7c2d0fa596f325832df98c3704f2c60553080f7127a58175"
dependencies = [
 "wasm-bindgen",
]

[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1011,6 +1026,34 @@ dependencies = [
]

[[package]]
name = "ring"
version = "0.16.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "024a1e66fea74c66c66624ee5622a7ff0e4b73a13b4f5c326ddb50c708944226"
dependencies = [
 "cc",
 "libc",
 "once_cell",
 "spin",
 "untrusted",
 "web-sys",
 "winapi",
]

[[package]]
name = "rustls"
version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "064fd21ff87c6e87ed4506e68beb42459caa4a0e2eb144932e6776768556980b"
dependencies = [
 "base64",
 "log",
 "ring",
 "sct",
 "webpki",
]

[[package]]
name = "ryu"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1029,6 +1072,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"

[[package]]
name = "sct"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3042af939fca8c3453b7af0f1c66e533a15a86169e39de2657310ade8f98d3c"
dependencies = [
 "ring",
 "untrusted",
]

[[package]]
name = "serde"
version = "1.0.120"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1125,6 +1178,12 @@ dependencies = [
]

[[package]]
name = "spin"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"

[[package]]
name = "static-web-server"
version = "2.0.0-beta.1"
dependencies = [
@@ -1254,6 +1313,17 @@ dependencies = [
]

[[package]]
name = "tokio-rustls"
version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6"
dependencies = [
 "rustls",
 "tokio",
 "webpki",
]

[[package]]
name = "tokio-stream"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1471,6 +1541,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"

[[package]]
name = "untrusted"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"

[[package]]
name = "url"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1538,6 +1614,7 @@ dependencies = [
 "serde_json",
 "serde_urlencoded",
 "tokio",
 "tokio-rustls",
 "tokio-stream",
 "tokio-tungstenite",
 "tokio-util",
@@ -1559,6 +1636,80 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93c6c3420963c5c64bca373b25e77acb562081b9bb4dd5bb864187742186cea9"

[[package]]
name = "wasm-bindgen"
version = "0.2.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3cd364751395ca0f68cafb17666eee36b63077fb5ecd972bbcd74c90c4bf736e"
dependencies = [
 "cfg-if 1.0.0",
 "wasm-bindgen-macro",
]

[[package]]
name = "wasm-bindgen-backend"
version = "0.2.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1114f89ab1f4106e5b55e688b828c0ab0ea593a1ea7c094b141b14cbaaec2d62"
dependencies = [
 "bumpalo",
 "lazy_static",
 "log",
 "proc-macro2",
 "quote",
 "syn",
 "wasm-bindgen-shared",
]

[[package]]
name = "wasm-bindgen-macro"
version = "0.2.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a6ac8995ead1f084a8dea1e65f194d0973800c7f571f6edd70adf06ecf77084"
dependencies = [
 "quote",
 "wasm-bindgen-macro-support",
]

[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5a48c72f299d80557c7c62e37e7225369ecc0c963964059509fbafe917c7549"
dependencies = [
 "proc-macro2",
 "quote",
 "syn",
 "wasm-bindgen-backend",
 "wasm-bindgen-shared",
]

[[package]]
name = "wasm-bindgen-shared"
version = "0.2.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e7811dd7f9398f14cc76efd356f98f03aa30419dea46aa810d71e819fc97158"

[[package]]
name = "web-sys"
version = "0.3.46"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "222b1ef9334f92a21d3fb53dc3fd80f30836959a90f9274a626d7e06315ba3c3"
dependencies = [
 "js-sys",
 "wasm-bindgen",
]

[[package]]
name = "webpki"
version = "0.21.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea"
dependencies = [
 "ring",
 "untrusted",
]

[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 1a6f913..1ba0b47 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -26,7 +26,7 @@ path = "src/bin/server.rs"

[dependencies]
tokio = { version = "1", features = ["rt-multi-thread"] }
warp = { git = "https://github.com/joseluisq/warp.git", branch = "0.3.x", features = ["compression"] }
warp = { git = "https://github.com/joseluisq/warp.git", branch = "0.3.x", features = ["tls","compression"] }
anyhow = "1.0"
tracing = "0.1"
tracing-subscriber = "0.2"
diff --git a/src/config.rs b/src/config.rs
index 7631c96..4589e6d 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -60,4 +60,16 @@ pub struct Config {
    )]
    /// Specify a optional CORS list of allowed origin hosts separated by comas. Host ports or protocols aren't being checked. Use an asterisk (*) to allow any host.
    pub cors_allow_origins: String,

    #[structopt(long, short = "t", env = "SERVER_HTTP2_TLS")]
    /// Enables HTTP/2 with TLS support.
    pub http2: bool,

    #[structopt(long, default_value = "", env = "SERVER_HTTP2_TLS_CERT")]
    /// Specify the file path to read the certificate.
    pub http2_tls_cert: String,

    #[structopt(long, default_value = "", env = "SERVER_HTTP2_TLS_KEY")]
    /// Specify the file path to read the private key.
    pub http2_tls_key: String,
}
diff --git a/src/server.rs b/src/server.rs
index e0ce105..ced7479 100644
--- a/src/server.rs
+++ b/src/server.rs
@@ -75,6 +75,11 @@ impl Server {
        // Public GET endpoint (default)
        let public_get_default = warp::get().and(base_dir_filter.clone());

        // HTTP/2 + TLS
        let http2 = opts.http2;
        let http2_tls_cert_path = opts.http2_tls_cert;
        let http2_tls_key_path = opts.http2_tls_key;

        // Public GET/HEAD endpoints with compression (deflate, gzip, brotli, none)
        match opts.compression.as_ref() {
            "brotli" => tokio::task::spawn(async move {
@@ -93,24 +98,40 @@ impl Server {
                        cors_enabled = ?true,
                        allowed_origins = ?cors_allowed_origins
                    );
                    warp::serve(
                    let server = warp::serve(
                        public_head.with(cors_filter.clone()).or(warp::get()
                            .and(filters::has_accept_encoding("br"))
                            .and(with_dir)
                            .with(cors_filter.clone())
                            .or(public_get_default.with(cors_filter))),
                    )
                    .run(addr)
                    .await
                    );
                    if http2 {
                        server
                            .tls()
                            .cert_path(http2_tls_cert_path)
                            .key_path(http2_tls_key_path)
                            .run(addr)
                            .await;
                    } else {
                        server.run(addr).await
                    }
                } else {
                    warp::serve(
                    let server = warp::serve(
                        public_head.or(warp::get()
                            .and(filters::has_accept_encoding("br"))
                            .and(with_dir)
                            .or(public_get_default)),
                    )
                    .run(addr)
                    .await
                    );
                    if http2 {
                        server
                            .tls()
                            .cert_path(http2_tls_cert_path)
                            .key_path(http2_tls_key_path)
                            .run(addr)
                            .await;
                    } else {
                        server.run(addr).await
                    }
                }
            }),
            "deflate" => tokio::task::spawn(async move {
@@ -129,24 +150,40 @@ impl Server {
                        cors_enabled = ?true,
                        allowed_origins = ?cors_allowed_origins
                    );
                    warp::serve(
                    let server = warp::serve(
                        public_head.with(cors_filter.clone()).or(warp::get()
                            .and(filters::has_accept_encoding("deflate"))
                            .and(with_dir)
                            .with(cors_filter.clone())
                            .or(public_get_default.with(cors_filter))),
                    )
                    .run(addr)
                    .await
                    );
                    if http2 {
                        server
                            .tls()
                            .cert_path(http2_tls_cert_path)
                            .key_path(http2_tls_key_path)
                            .run(addr)
                            .await;
                    } else {
                        server.run(addr).await
                    }
                } else {
                    warp::serve(
                    let server = warp::serve(
                        public_head.or(warp::get()
                            .and(filters::has_accept_encoding("deflate"))
                            .and(with_dir)
                            .or(public_get_default)),
                    )
                    .run(addr)
                    .await
                    );
                    if http2 {
                        server
                            .tls()
                            .cert_path(http2_tls_cert_path)
                            .key_path(http2_tls_key_path)
                            .run(addr)
                            .await;
                    } else {
                        server.run(addr).await
                    }
                }
            }),
            "gzip" => tokio::task::spawn(async move {
@@ -165,24 +202,40 @@ impl Server {
                        cors_enabled = ?true,
                        allowed_origins = ?cors_allowed_origins
                    );
                    warp::serve(
                    let server = warp::serve(
                        public_head.with(cors_filter.clone()).or(warp::get()
                            .and(filters::has_accept_encoding("gzip"))
                            .and(with_dir)
                            .with(cors_filter.clone())
                            .or(public_get_default.with(cors_filter))),
                    )
                    .run(addr)
                    .await
                    );
                    if http2 {
                        server
                            .tls()
                            .cert_path(http2_tls_cert_path)
                            .key_path(http2_tls_key_path)
                            .run(addr)
                            .await;
                    } else {
                        server.run(addr).await
                    }
                } else {
                    warp::serve(
                    let server = warp::serve(
                        public_head.or(warp::get()
                            .and(filters::has_accept_encoding("gzip"))
                            .and(with_dir)
                            .or(public_get_default)),
                    )
                    .run(addr)
                    .await
                    );
                    if http2 {
                        server
                            .tls()
                            .cert_path(http2_tls_cert_path)
                            .key_path(http2_tls_key_path)
                            .run(addr)
                            .await;
                    } else {
                        server.run(addr).await
                    }
                }
            }),
            _ => tokio::task::spawn(async move {
@@ -194,13 +247,29 @@ impl Server {
                    let public_get_default = warp::get()
                        .and(base_dir_filter.clone())
                        .with(cors_filter.clone());
                    warp::serve(public_head.or(public_get_default.with(cors_filter)))
                        .run(addr)
                        .await
                    let server = warp::serve(public_head.or(public_get_default.with(cors_filter)));
                    if http2 {
                        server
                            .tls()
                            .cert_path(http2_tls_cert_path)
                            .key_path(http2_tls_key_path)
                            .run(addr)
                            .await;
                    } else {
                        server.run(addr).await
                    }
                } else {
                    warp::serve(public_head.or(public_get_default))
                        .run(addr)
                        .await
                    let server = warp::serve(public_head.or(public_get_default));
                    if http2 {
                        server
                            .tls()
                            .cert_path(http2_tls_cert_path)
                            .key_path(http2_tls_key_path)
                            .run(addr)
                            .await;
                    } else {
                        server.run(addr).await
                    }
                }
            }),
        };