From 343711b291add03bb727304fdada863b88deb13d Mon Sep 17 00:00:00 2001 From: Jose Quintana Date: Tue, 5 Jan 2021 01:53:10 +0100 Subject: [PATCH] refactor: code base for v2 --- .gitignore | 1 + Cargo.lock | 1096 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Cargo.toml | 20 ++++++-------------- README.md | 159 ++------------------------------------------------------------------------------------------------------------------------------------------------------------- public/404.html | 28 ++-------------------------- public/50x.html | 28 ++-------------------------- public/index.html | 14 ++++---------- sample.env | 4 ---- src/bin/server.rs | 36 ++++++++++++++++++++++++++++++++++++ src/config.rs | 56 -------------------------------------------------------- src/core/config.rs | 21 +++++++++++++++++++++ src/core/helpers.rs | 35 +++++++++++++++++++++++++++++++++++ src/core/logger.rs | 45 +++++++++++++++++++++++++++++++++++++++++++++ src/core/mod.rs | 7 +++++++ src/core/rejection.rs | 23 +++++++++++++++++++++++ src/core/signal_manager.rs | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/error_page.rs | 80 -------------------------------------------------------------------------------- src/gzip.rs | 37 ------------------------------------- src/helpers.rs | 35 ----------------------------------- src/lib.rs | 3 +++ src/logger.rs | 66 ------------------------------------------------------------------ src/main.rs | 320 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- src/signal_manager.rs | 56 -------------------------------------------------------- src/staticfiles.rs | 100 ---------------------------------------------------------------------------------------------------- 24 files changed, 1031 insertions(+), 1295 deletions(-) create mode 100644 src/bin/server.rs delete mode 100644 src/config.rs create mode 100644 src/core/config.rs create mode 100644 src/core/helpers.rs create mode 100644 src/core/logger.rs create mode 100644 src/core/mod.rs create mode 100644 src/core/rejection.rs create mode 100644 src/core/signal_manager.rs delete mode 100644 src/error_page.rs delete mode 100644 src/gzip.rs delete mode 100644 src/helpers.rs create mode 100644 src/lib.rs delete mode 100644 src/logger.rs delete mode 100644 src/main.rs delete mode 100644 src/signal_manager.rs delete mode 100644 src/staticfiles.rs diff --git a/.gitignore b/.gitignore index 820521f..7b070eb 100644 --- a/.gitignore +++ b/.gitignore @@ -15,5 +15,6 @@ **/*.env release .vscode +TODO !sample.env diff --git a/Cargo.lock b/Cargo.lock index c601907..f142856 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -16,19 +16,48 @@ dependencies = [ ] [[package]] +name = "alloc-no-stdlib" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5192ec435945d87bc2f70992b4d818154b5feede43c09fb7592146374eac90a6" + +[[package]] +name = "alloc-stdlib" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "697ed7edc0f1711de49ce108c541623a0af97c6c60b2f6e2b65229847ac843c2" +dependencies = [ + "alloc-no-stdlib", +] + +[[package]] name = "ansi_term" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" dependencies = [ - "winapi", + "winapi 0.3.9", ] [[package]] -name = "antidote" -version = "1.0.0" +name = "anyhow" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34fde25430d87a9388dadbe6e34d7f72a462c8b43ac8d309b42b0a8505d7e2a5" +checksum = "ee67c11feeac938fae061b232e38e0b6d94f97a9df10e6271319325ac4c56a86" + +[[package]] +name = "async-compression" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b72c1f1154e234325b50864a349b9c8e56939e266a4c307c0f159812df2f9537" +dependencies = [ + "brotli", + "bytes", + "flate2", + "futures-core", + "memchr", + "pin-project-lite 0.2.0", +] [[package]] name = "atty" @@ -38,7 +67,7 @@ checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ "hermit-abi", "libc", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -55,19 +84,82 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" [[package]] name = "base64" -version = "0.9.3" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" + +[[package]] +name = "bitflags" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" + +[[package]] +name = "block-buffer" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" dependencies = [ + "block-padding", + "byte-tools", "byteorder", + "generic-array 0.12.3", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array 0.14.4", +] + +[[package]] +name = "block-padding" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" +dependencies = [ + "byte-tools", +] + +[[package]] +name = "brotli" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f29919120f08613aadcd4383764e00526fc9f18b6c0895814faeed0dd78613e" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1052e1c3b8d4d80eb84a8b94f0a1498797b5fb96314c001156a1c761940ef4ec" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + +[[package]] +name = "buf_redux" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b953a6887648bb07a535631f2bc00fbdb2a2216f135552cb3f534ed136b9c07f" +dependencies = [ + "memchr", "safemem", ] [[package]] -name = "bitflags" -version = "1.2.1" +name = "byte-tools" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" [[package]] name = "byteorder" @@ -76,6 +168,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" [[package]] +name = "bytes" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" + +[[package]] name = "cc" version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -103,7 +201,7 @@ dependencies = [ "num-integer", "num-traits", "time", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -131,31 +229,45 @@ dependencies = [ ] [[package]] -name = "core-foundation" -version = "0.9.1" +name = "cpuid-bool" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634" + +[[package]] +name = "crc32fast" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a89e2ae426ea83155dccf10c0fa6b1463ef6d5fcb44cee0b224a408fa640a62" +checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" dependencies = [ - "core-foundation-sys", - "libc", + "cfg-if 1.0.0", ] [[package]] -name = "core-foundation-sys" -version = "0.8.2" +name = "digest" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b" +checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +dependencies = [ + "generic-array 0.12.3", +] [[package]] -name = "crc32fast" -version = "1.2.1" +name = "digest" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "cfg-if 1.0.0", + "generic-array 0.14.4", ] [[package]] +name = "dtoa" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88d7ed2934d741c6b37e33e3832298e8850b53fd2d2bea03873375596c7cea4e" + +[[package]] name = "env_logger" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -163,12 +275,18 @@ checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" dependencies = [ "atty", "humantime", - "log 0.4.11", + "log", "regex", "termcolor", ] [[package]] +name = "fake-simd" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" + +[[package]] name = "flate2" version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -181,19 +299,20 @@ dependencies = [ ] [[package]] -name = "foreign-types" -version = "0.3.2" +name = "fnv" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] -name = "foreign-types-shared" -version = "0.1.1" +name = "form_urlencoded" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" +checksum = "ece68d15c92e84fa4f19d3780f1294e5ca82a78a6d515f1efaabcc144688be00" +dependencies = [ + "matches", + "percent-encoding", +] [[package]] name = "fs_extra" @@ -208,6 +327,106 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" [[package]] +name = "fuchsia-zircon" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" +dependencies = [ + "bitflags", + "fuchsia-zircon-sys", +] + +[[package]] +name = "fuchsia-zircon-sys" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" + +[[package]] +name = "futures" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b3b0c040a1fe6529d30b3c5944b280c7f0dcb2930d2c3062bca967b602583d0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b7109687aa4e177ef6fe84553af6280ef2778bdb7783ba44c9dc3399110fe64" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "847ce131b72ffb13b6109a221da9ad97a64cbe48feb1028356b836b47b8f1748" + +[[package]] +name = "futures-io" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "611834ce18aaa1bd13c4b374f5d653e1027cf99b6b502584ff8c9a64413b30bb" + +[[package]] +name = "futures-sink" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f878195a49cee50e006b02b93cf7e0a95a38ac7b776b4c4d9cc1207cd20fcb3d" + +[[package]] +name = "futures-task" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c554eb5bf48b2426c4771ab68c6b14468b6e76cc90996f528c3338d761a4d0d" +dependencies = [ + "once_cell", +] + +[[package]] +name = "futures-util" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d304cff4a7b99cfb7986f7d43fbe93d175e72e704a8860787cc95e9ffd85cbd2" +dependencies = [ + "futures-core", + "futures-sink", + "futures-task", + "pin-project 1.0.2", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" +dependencies = [ + "typenum", +] + +[[package]] +name = "generic-array" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] name = "getrandom" version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -219,6 +438,57 @@ dependencies = [ ] [[package]] +name = "h2" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e4728fd124914ad25e99e3d15a9361a879f6620f63cb56bbb08f95abb97a535" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", + "tracing-futures", +] + +[[package]] +name = "hashbrown" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" + +[[package]] +name = "headers" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed18eb2459bf1a09ad2d6b1547840c3e5e62882fa09b9a6a20b1de8e3228848f" +dependencies = [ + "base64", + "bitflags", + "bytes", + "headers-core", + "http", + "mime", + "sha-1 0.8.2", + "time", +] + +[[package]] +name = "headers-core" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" +dependencies = [ + "http", +] + +[[package]] name = "heck" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -237,12 +507,39 @@ dependencies = [ ] [[package]] +name = "http" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84129d298a6d57d246960ff8eb831ca4af3f96d29e2e28848dae275408658e26" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13d5ff830006f7646652e057693569bfe0d51760c0085a071769d142a205111b" +dependencies = [ + "bytes", + "http", +] + +[[package]] name = "httparse" version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" [[package]] +name = "httpdate" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "494b4d60369511e7dea41cf646832512a94e542f68bb9c49e54518e0f468eb47" + +[[package]] name = "humantime" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -253,39 +550,33 @@ dependencies = [ [[package]] name = "hyper" -version = "0.10.16" +version = "0.13.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a0652d9a2609a968c14be1a9ea00bf4b1d64e2e1f53a1b51b6fff3a6e829273" +checksum = "f6ad767baac13b44d4529fcf58ba2cd0995e36e7b435bc5b039de6f47e880dbf" dependencies = [ - "base64", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", "httparse", - "language-tags", - "log 0.3.9", - "mime", - "num_cpus", - "time", - "traitobject", - "typeable", - "unicase", - "url", -] - -[[package]] -name = "hyper-native-tls" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d375598f442742b0e66208ee12501391f1c7ac0bafb90b4fe53018f81f06068" -dependencies = [ - "antidote", - "hyper", - "native-tls", + "httpdate", + "itoa", + "pin-project 1.0.2", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", ] [[package]] name = "idna" -version = "0.1.5" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" +checksum = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" dependencies = [ "matches", "unicode-bidi", @@ -293,57 +584,38 @@ dependencies = [ ] [[package]] -name = "iron" -version = "0.6.1" +name = "indexmap" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6d308ca2d884650a8bf9ed2ff4cb13fbb2207b71f64cda11dc9b892067295e8" +checksum = "4fb1fa934250de4de8aef298d81c729a7d33d8c239daa3a7575e6b92bfc7313b" dependencies = [ - "hyper", - "log 0.3.9", - "mime_guess", - "modifier", - "num_cpus", - "plugin", - "typemap", - "url", + "autocfg 1.0.1", + "hashbrown", ] [[package]] -name = "iron-cors" -version = "0.8.0" +name = "input_buffer" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24b02b8856c7f14e443c483e802cf0ce693f3bec19f49d2c9a242b18f88c9b70" +checksum = "19a8a95243d5a0398cae618ec29477c6e3cb631152be5c19481f80bc71559754" dependencies = [ - "iron", - "log 0.4.11", + "bytes", ] [[package]] -name = "iron-test" -version = "0.6.0" +name = "iovec" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1944bcf30f8b3f51ebf01e715517dd9755e9480934778d6de70179a41d283c1" +checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" dependencies = [ - "hyper", - "iron", - "log 0.3.9", - "url", - "uuid", + "libc", ] [[package]] -name = "iron_staticfile_middleware" -version = "0.4.2" -source = "git+https://github.com/joseluisq/iron-staticfile-middleware.git?tag=v0.4.2#1681b273edd087ff470d77d2c3fa7d64fc547e6f" -dependencies = [ - "iron", - "log 0.4.11", - "mime", - "mime_guess", - "rustc-serialize", - "time", - "url", -] +name = "itoa" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" [[package]] name = "jemalloc-sys" @@ -367,10 +639,14 @@ dependencies = [ ] [[package]] -name = "language-tags" +name = "kernel32-sys" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" +checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +dependencies = [ + "winapi 0.2.8", + "winapi-build", +] [[package]] name = "lazy_static" @@ -386,15 +662,6 @@ checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb" [[package]] name = "log" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" -dependencies = [ - "log 0.4.11", -] - -[[package]] -name = "log" version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" @@ -416,22 +683,17 @@ checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" [[package]] name = "mime" -version = "0.2.6" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0" -dependencies = [ - "log 0.3.9", -] +checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" [[package]] name = "mime_guess" -version = "1.8.8" +version = "2.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216929a5ee4dd316b1702eedf5e74548c123d370f47841ceaac38ca154690ca3" +checksum = "2684d4c2e97d99848d30b324b00c8fcc7e5c897b7cbb5819b09e7c90e8baf212" dependencies = [ "mime", - "phf", - "phf_codegen", "unicase", ] @@ -446,27 +708,96 @@ dependencies = [ ] [[package]] -name = "modifier" -version = "0.1.0" +name = "mio" +version = "0.6.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f5c9112cb662acd3b204077e0de5bc66305fa8df65c8019d5adb10e9ab6e58" +checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4" +dependencies = [ + "cfg-if 0.1.10", + "fuchsia-zircon", + "fuchsia-zircon-sys", + "iovec", + "kernel32-sys", + "libc", + "log", + "miow 0.2.2", + "net2", + "slab", + "winapi 0.2.8", +] [[package]] -name = "native-tls" -version = "0.2.7" +name = "mio-named-pipes" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8d96b2e1c8da3957d58100b09f102c6d9cfdfced01b7ec5a8974044bb09dbd4" +checksum = "0840c1c50fd55e521b247f949c241c9997709f23bd7f023b9762cd561e935656" dependencies = [ - "lazy_static", + "log", + "mio", + "miow 0.3.6", + "winapi 0.3.9", +] + +[[package]] +name = "mio-uds" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0" +dependencies = [ + "iovec", "libc", - "log 0.4.11", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", + "mio", +] + +[[package]] +name = "miow" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d" +dependencies = [ + "kernel32-sys", + "net2", + "winapi 0.2.8", + "ws2_32-sys", +] + +[[package]] +name = "miow" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a33c1b55807fbed163481b5ba66db4b2fa6cde694a5027be10fb724206c5897" +dependencies = [ + "socket2", + "winapi 0.3.9", +] + +[[package]] +name = "multipart" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8209c33c951f07387a8497841122fc6f712165e3f9bda3e6be4645b58188f676" +dependencies = [ + "buf_redux", + "httparse", + "log", + "mime", + "mime_guess", + "quick-error", + "rand 0.6.5", + "safemem", "tempfile", + "twoway", +] + +[[package]] +name = "net2" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "391630d12b68002ae1e25e8f974306474966550ad82dac6886fb8910c19568ae" +dependencies = [ + "cfg-if 0.1.10", + "libc", + "winapi 0.3.9", ] [[package]] @@ -512,107 +843,86 @@ dependencies = [ ] [[package]] -name = "openssl" -version = "0.10.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038d43985d1ddca7a9900630d8cd031b56e4794eecc2e9ea39dd17aa04399a70" -dependencies = [ - "bitflags", - "cfg-if 1.0.0", - "foreign-types", - "lazy_static", - "libc", - "openssl-sys", -] - -[[package]] -name = "openssl-probe" -version = "0.1.2" +name = "once_cell" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" +checksum = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0" [[package]] -name = "openssl-src" -version = "111.13.0+1.1.1i" +name = "opaque-debug" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "045e4dc48af57aad93d665885789b43222ae26f4886494da12d1ed58d309dcb6" -dependencies = [ - "cc", -] +checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" [[package]] -name = "openssl-sys" -version = "0.9.60" +name = "opaque-debug" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "921fc71883267538946025deffb622905ecad223c28efbfdef9bb59a0175f3e6" -dependencies = [ - "autocfg 1.0.1", - "cc", - "libc", - "openssl-src", - "pkg-config", - "vcpkg", -] +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "percent-encoding" -version = "1.0.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" +checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" [[package]] -name = "phf" -version = "0.7.24" +name = "pin-project" +version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3da44b85f8e8dfaec21adae67f95d93244b2ecf6ad2a692320598dcc8e6dd18" +checksum = "2ffbc8e94b38ea3d2d8ba92aea2983b503cd75d0888d75b86bb37970b5698e15" dependencies = [ - "phf_shared", + "pin-project-internal 0.4.27", ] [[package]] -name = "phf_codegen" -version = "0.7.24" +name = "pin-project" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b03e85129e324ad4166b06b2c7491ae27fe3ec353af72e72cd1654c7225d517e" +checksum = "9ccc2237c2c489783abd8c4c80e5450fc0e98644555b1364da68cc29aa151ca7" dependencies = [ - "phf_generator", - "phf_shared", + "pin-project-internal 1.0.2", ] [[package]] -name = "phf_generator" -version = "0.7.24" +name = "pin-project-internal" +version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09364cc93c159b8b06b1f4dd8a4398984503483891b0c26b867cf431fb132662" +checksum = "65ad2ae56b6abe3a1ee25f15ee605bacadb9a764edaba9c2bf4103800d4a1895" dependencies = [ - "phf_shared", - "rand 0.6.5", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "phf_shared" -version = "0.7.24" +name = "pin-project-internal" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "234f71a15de2288bcb7e3b6515828d22af7ec8598ee6d24c3b526fa0a80b67a0" +checksum = "f8e8d2bf0b23038a4424865103a4df472855692821aab4e4f5c3312d461d9e5f" dependencies = [ - "siphasher", - "unicase", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "pkg-config" -version = "0.3.19" +name = "pin-project-lite" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" +checksum = "c917123afa01924fc84bb20c4c03f004d9c38e5127e3c039bbf7f4b9c76a2f6b" [[package]] -name = "plugin" -version = "0.2.6" +name = "pin-project-lite" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a6a0dc3910bc8db877ffed8e457763b317cf880df4ae19109b9f77d277cf6e0" -dependencies = [ - "typemap", -] +checksum = "6b063f57ec186e6140e2b8b6921e5f1bd89c7356dda5b33acc5401203ca6131c" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "ppv-lite86" @@ -630,7 +940,7 @@ dependencies = [ "proc-macro2", "quote", "syn", - "version_check 0.9.2", + "version_check", ] [[package]] @@ -641,7 +951,7 @@ checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ "proc-macro2", "quote", - "version_check 0.9.2", + "version_check", ] [[package]] @@ -670,29 +980,6 @@ dependencies = [ [[package]] name = "rand" -version = "0.3.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c" -dependencies = [ - "libc", - "rand 0.4.6", -] - -[[package]] -name = "rand" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" -dependencies = [ - "fuchsia-cprng", - "libc", - "rand_core 0.3.1", - "rdrand", - "winapi", -] - -[[package]] -name = "rand" version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" @@ -707,7 +994,7 @@ dependencies = [ "rand_os", "rand_pcg", "rand_xorshift", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -802,7 +1089,7 @@ checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" dependencies = [ "libc", "rand_core 0.4.2", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -816,7 +1103,7 @@ dependencies = [ "libc", "rand_core 0.4.2", "rdrand", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -877,14 +1164,14 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" dependencies = [ - "winapi", + "winapi 0.3.9", ] [[package]] -name = "rustc-serialize" -version = "0.3.24" +name = "ryu" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "safemem" @@ -893,36 +1180,63 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" [[package]] -name = "schannel" -version = "0.1.19" +name = "scoped-tls" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" + +[[package]] +name = "serde" +version = "1.0.118" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06c64263859d87aa2eb554587e2d23183398d617427327cf2b3d0ed8c69e4800" + +[[package]] +name = "serde_json" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" +checksum = "4fceb2595057b6891a4ee808f70054bd2d12f0e97f1cbb78689b59f676df325a" dependencies = [ - "lazy_static", - "winapi", + "itoa", + "ryu", + "serde", ] [[package]] -name = "security-framework" -version = "2.0.0" +name = "serde_urlencoded" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1759c2e3c8580017a484a7ac56d3abc5a6c1feadf88db2f3633f12ae4268c69" +checksum = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97" dependencies = [ - "bitflags", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", + "dtoa", + "itoa", + "serde", + "url", ] [[package]] -name = "security-framework-sys" -version = "2.0.0" +name = "sha-1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f99b9d5e26d2a71633cc4f2ebae7cc9f874044e0c351a27e17892d76dce5678b" +checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df" dependencies = [ - "core-foundation-sys", - "libc", + "block-buffer 0.7.3", + "digest 0.8.1", + "fake-simd", + "opaque-debug 0.2.3", +] + +[[package]] +name = "sha-1" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce3cdf1b5e620a498ee6f2a171885ac7e22f0e12089ec4b3d22b84921792507c" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if 1.0.0", + "cpuid-bool", + "digest 0.9.0", + "opaque-debug 0.3.0", ] [[package]] @@ -936,31 +1250,45 @@ dependencies = [ ] [[package]] -name = "siphasher" -version = "0.2.3" +name = "signal-hook-registry" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16f1d0fef1604ba8f7a073c7e701f213e056707210e9020af4528e0101ce11a6" +dependencies = [ + "libc", +] + +[[package]] +name = "slab" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac" +checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" + +[[package]] +name = "socket2" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "winapi 0.3.9", +] [[package]] name = "static-web-server" -version = "1.12.0" +version = "0.0.0" dependencies = [ + "anyhow", "chrono", "env_logger", - "flate2", - "hyper", - "hyper-native-tls", - "iron", - "iron-cors", - "iron-test", - "iron_staticfile_middleware", "jemallocator", - "log 0.4.11", + "log", "nix", - "openssl", "signal", "structopt", - "tempdir", + "tokio", + "warp", ] [[package]] @@ -1005,16 +1333,6 @@ dependencies = [ ] [[package]] -name = "tempdir" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" -dependencies = [ - "rand 0.4.6", - "remove_dir_all", -] - -[[package]] name = "tempfile" version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1025,7 +1343,7 @@ dependencies = [ "rand 0.7.3", "redox_syscall", "remove_dir_all", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -1063,7 +1381,7 @@ checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" dependencies = [ "libc", "wasi 0.10.0+wasi-snapshot-preview1", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -1082,33 +1400,151 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] -name = "traitobject" -version = "0.1.0" +name = "tokio" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" +checksum = "099837d3464c16a808060bb3f02263b412f6fafcb5d01c533d309985fbeebe48" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "iovec", + "lazy_static", + "libc", + "memchr", + "mio", + "mio-named-pipes", + "mio-uds", + "num_cpus", + "pin-project-lite 0.1.11", + "signal-hook-registry", + "slab", + "tokio-macros", + "winapi 0.3.9", +] [[package]] -name = "typeable" -version = "0.1.2" +name = "tokio-macros" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" +checksum = "e44da00bfc73a25f814cd8d7e57a68a5c31b74b3152a0a1d1f590c97ed06265a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] -name = "typemap" -version = "0.3.3" +name = "tokio-tungstenite" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d9e878ad426ca286e4dcae09cbd4e1973a7f8987d97570e2469703dd7f5720c" +dependencies = [ + "futures-util", + "log", + "pin-project 0.4.27", + "tokio", + "tungstenite", +] + +[[package]] +name = "tokio-util" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "log", + "pin-project-lite 0.1.11", + "tokio", +] + +[[package]] +name = "tower-service" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "653be63c80a3296da5551e1bfd2cca35227e13cdd08c6668903ae2f4f77aa1f6" +checksum = "e987b6bf443f4b5b3b6f38704195592cca41c5bb7aedd3c3693c7081f8289860" + +[[package]] +name = "tracing" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f47026cdc4080c07e49b37087de021820269d996f581aac150ef9e5583eefe3" dependencies = [ - "unsafe-any", + "cfg-if 1.0.0", + "log", + "pin-project-lite 0.2.0", + "tracing-core", ] [[package]] +name = "tracing-core" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f50de3927f93d202783f4513cda820ab47ef17f624b03c096e86ef00c67e6b5f" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "tracing-futures" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab7bb6f14721aa00656086e9335d363c5c8747bae02ebe32ea2c7dece5689b4c" +dependencies = [ + "pin-project 0.4.27", + "tracing", +] + +[[package]] +name = "try-lock" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" + +[[package]] +name = "tungstenite" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0308d80d86700c5878b9ef6321f020f29b1bb9d5ff3cab25e75e23f3a492a23" +dependencies = [ + "base64", + "byteorder", + "bytes", + "http", + "httparse", + "input_buffer", + "log", + "rand 0.7.3", + "sha-1 0.9.2", + "url", + "utf-8", +] + +[[package]] +name = "twoway" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59b11b2b5241ba34be09c3cc85a36e56e48f9888862e19cedf23336d35316ed1" +dependencies = [ + "memchr", +] + +[[package]] +name = "typenum" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" + +[[package]] name = "unicase" -version = "1.4.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" +checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" dependencies = [ - "version_check 0.1.5", + "version_check", ] [[package]] @@ -1148,39 +1584,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" [[package]] -name = "unsafe-any" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f30360d7979f5e9c6e6cea48af192ea8fab4afb3cf72597154b8f08935bc9c7f" -dependencies = [ - "traitobject", -] - -[[package]] name = "url" -version = "1.7.2" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" +checksum = "5909f2b0817350449ed73e8bcd81c8c3c8d9a7a5d8acba4b27db277f1868976e" dependencies = [ + "form_urlencoded", "idna", "matches", "percent-encoding", ] [[package]] -name = "uuid" -version = "0.5.1" +name = "urlencoding" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcc7e3b898aa6f6c08e5295b6c89258d1331e9ac578cc992fb818759951bdc22" -dependencies = [ - "rand 0.3.23", -] +checksum = "c9232eb53352b4442e40d7900465dfc534e8cb2dc8f18656fcb2ac16112b5593" [[package]] -name = "vcpkg" -version = "0.2.11" +name = "utf-8" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b00bca6106a5e23f3eee943593759b7fcddb00554332e856d990c893966879fb" +checksum = "05e42f7c18b8f902290b009cde6d651262f956c98bc51bca4cd1d511c9cd85c7" [[package]] name = "vec_map" @@ -1190,12 +1615,6 @@ checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" [[package]] name = "version_check" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" - -[[package]] -name = "version_check" version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" @@ -1207,6 +1626,45 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" [[package]] +name = "want" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +dependencies = [ + "log", + "try-lock", +] + +[[package]] +name = "warp" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f41be6df54c97904af01aa23e613d4521eed7ab23537cede692d4058f6449407" +dependencies = [ + "async-compression", + "bytes", + "futures", + "headers", + "http", + "hyper", + "log", + "mime", + "mime_guess", + "multipart", + "pin-project 0.4.27", + "scoped-tls", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-tungstenite", + "tower-service", + "tracing", + "tracing-futures", + "urlencoding", +] + +[[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1220,6 +1678,12 @@ checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" [[package]] name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" + +[[package]] +name = "winapi" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" @@ -1229,6 +1693,12 @@ dependencies = [ ] [[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" + +[[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1240,7 +1710,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" dependencies = [ - "winapi", + "winapi 0.3.9", ] [[package]] @@ -1248,3 +1718,13 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "ws2_32-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" +dependencies = [ + "winapi 0.2.8", + "winapi-build", +] diff --git a/Cargo.toml b/Cargo.toml index 23eb974..d4bc078 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,47 +1,39 @@ [package] name = "static-web-server" -version = "1.12.0" +version = "0.0.0" authors = ["Jose Quintana "] license = "MIT OR Apache-2.0" description = "A blazing fast static files-serving web server powered by Rust Iron." repository = "https://github.com/joseluisq/static-web-server" readme = "README.md" keywords = [ - "docker-image", "static-web-server", "file-server", "http-server", "linux", "darwin", "musl-libc", - "x86-64" + "x86-64", + "docker-image" ] categories = ["network-programming", "web-programming::http-server"] edition = "2018" include = ["src/**/*", "Cargo.toml", "Cargo.lock"] [dependencies] -iron = "0.6" +tokio = { version = "0.2", features = ["full"] } +warp = { version = "0.2", features = ["compression"] } log = "0.4" chrono = "0.4" +anyhow = "1.0" env_logger = "0.7" structopt = "0.3" -flate2 = "1.0" -iron_staticfile_middleware = { git = "https://github.com/joseluisq/iron-staticfile-middleware.git", tag = "v0.4.2" } -hyper-native-tls = "0.3" nix = "0.14" signal = "0.7" -iron-cors = "0.8" [target.'cfg(all(target_env = "musl", target_pointer_width = "64"))'.dependencies.jemallocator] version = "0.3" -[dev-dependencies] -openssl = { version = "0.10", features = ["vendored"] } -hyper = "0.10" -iron-test = "0.6" -tempdir = "0.3" - [profile.release] lto = "fat" codegen-units = 1 diff --git a/README.md b/README.md index bb1056b..debe834 100644 --- a/README.md +++ b/README.md @@ -1,163 +1,8 @@ # Static Web Server [![Docker Image Version (tag latest semver)](https://img.shields.io/docker/v/joseluisq/static-web-server/1)](https://hub.docker.com/r/joseluisq/static-web-server/) [![Build Status](https://travis-ci.com/joseluisq/static-web-server.svg?branch=master)](https://travis-ci.com/joseluisq/static-web-server) [![Docker Image Size (tag)](https://img.shields.io/docker/image-size/joseluisq/static-web-server/1)](https://hub.docker.com/r/joseluisq/static-web-server/tags) [![Docker Image](https://img.shields.io/docker/pulls/joseluisq/static-web-server.svg)](https://hub.docker.com/r/joseluisq/static-web-server/) -> A blazing fast static files-serving web server powered by [Rust Iron](https://github.com/iron/iron). :zap: +**STATUS:** This is a WIP v2 release under **active** development. For stable releases and contributions please refer to [master](https://github.com/joseluisq/static-web-server) branch. -**Static Web Server** is a very small and fast production-ready web server to serving static web files or assets. - -## Features - -- Built with [Rust](https://rust-lang.org) which is focused on [safety, speed, and concurrency](https://kornel.ski/rust-c-speed). -- Memory safety and reduced overhead of CPU and RAM resources. -- Blazing fast static files-serving thanks to [Rust Iron](https://github.com/iron/iron) and [Hyper](https://github.com/hyperium/hyper). -- Suitable for lightweight [GNU/Linux Docker containers](https://hub.docker.com/r/joseluisq/static-web-server/tags). It's a fully __4MB__ static binary thanks to [Rust and Musl libc](https://doc.rust-lang.org/edition-guide/rust-2018/platform-and-target-support/musl-support-for-fully-static-binaries.html) (`x86_64-unknown-linux-musl`). -- Gzip compression on demand via [accept-encoding](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding) header. -- [Partial Content Delivery](https://en.wikipedia.org/wiki/Byte_serving) support for byte-serving of large files. -- [Cache control headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control) for assets. -- [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) support. -- [HEAD](https://tools.ietf.org/html/rfc7231#section-4.3.2) responses support. -- [TLS](https://www.openssl.org/) support via [Rust Native TLS](https://docs.rs/native-tls/0.2.3/native_tls/) crate. -- Lightweight and configurable logging. -- 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 - -Available for download/install via following methods: - -- **Docker Image** on [hub.docker.com/r/joseluisq/static-web-server/](https://hub.docker.com/r/joseluisq/static-web-server/) -- **Release binaries** for `GNU/Linux` and `MacOS` x86_64 on [github.com/joseluisq/static-web-server/releases](https://github.com/joseluisq/static-web-server/releases). - -## Usage - -Server can be configured either via environment variables or their equivalent command-line arguments. - -### Environment Variables - -| Variable | Description | Default | -| --- | --- | --- | -| `SERVER_NAME` | Name for server. | Default `my-static-server`. | -| `SERVER_HOST` | Host address (E.g 127.0.0.1). | Default `[::]`. | -| `SERVER_PORT` | Host port. | Default `80`. | -| `SERVER_ROOT` | Root directory path of static files. | Default `./public`. | -| `SERVER_ASSETS` | Assets directory path for add cache headers functionality. | Default `./public/assets`. | -| `SERVER_LOG_LEVEL` | Specify a logging level in lower case (see [log::LevelFilter](https://docs.rs/log/0.4.10/log/enum.LevelFilter.html)). | Default `error` | -| `SERVER_ERROR_PAGE_404` | HTML file path for 404 errors. | If path is not specified or simply don't exists then server will use a generic HTML error message. Default `./public/404.html`. -| `SERVER_ERROR_PAGE_50X` | HTML file path for 50x errors. | If path is not specified or simply don't exists then server will use a generic HTML error message. Default `./public/50x.html` | -| `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 - -CLI arguments listed with `static-web-server -h`. - -``` -static-web-server 1.10.0 -A blazing fast static files-serving web server powered by Rust Iron - -USAGE: - static-web-server [OPTIONS] - -FLAGS: - -h, --help Prints help information - -V, --version Prints version information - -OPTIONS: - --assets - Assets directory path for add cache headers functionality [env: SERVER_ASSETS=] [default: ./public/assets] - - --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 [env: SERVER_CORS_ALLOW_ORIGINS=] [default: ] - --host Host address (E.g 127.0.0.1) [env: SERVER_HOST=] [default: [::]] - --log-level - Specify a logging level in lower case [env: SERVER_LOG_LEVEL=] [default: error] - - --name Name for server [env: SERVER_NAME=] [default: my-static-server] - --page404 - HTML file path for 404 errors. If path is not specified or simply don't exists then server will use a - generic HTML error message [env: SERVER_ERROR_PAGE_404=] [default: ./public/404.html] - --page50x - HTML file path for 50x errors. If path is not specified or simply don't exists then server will use a - generic HTML error message [env: SERVER_ERROR_PAGE_50X=] [default: ./public/50x.html] - --port Host port [env: SERVER_PORT=] [default: 80] - --root - Root directory path of static files [env: SERVER_ROOT=] [default: ./public] - - --tls Enables TLS/SSL support [env: SERVER_TLS=] - --tls-pkcs12 - A cryptographic identity PKCS #12 bundle file path containing a X509 certificate along with its - 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 - -TLS/SSL support is provided by [Rust Native TLS](https://docs.rs/native-tls/0.2.3/native_tls/struct.Identity.html#method.from_pkcs12) crate which supports [PKCS #12 cryptographic identity](https://en.wikipedia.org/wiki/PKCS_12). -An identity is an [X509 certificate](https://en.wikipedia.org/wiki/X.509) certificate along with its corresponding private key and chain of certificates to a trusted root. - -For instance, identity files (`.p12` or `.pfx`) can be generated using the [OpenSSL SSL/TLS Toolkit](https://www.openssl.org/docs/manmaster/man1/pkcs12.html): - -Generate a self-signed certificate (optional): - -```sh -openssl req -x509 -newkey rsa:4096 -nodes -keyout local.key -out local.crt -days 3650 -``` - -Generate a PKCS #12 indentity file (using an existing certificate and private key): - -```sh -openssl pkcs12 -export -out identity.p12 -inkey local.key -in local.crt -password pass:my_password -``` - -## Docker stack - -Example using [Traefik Proxy](https://traefik.io/): - -```yaml -version: "3.3" - -services: - web: - image: joseluisq/static-web-server:1 - environment: - - SERVER_NAME=my-server - - SERVER_HOST=127.0.0.1 - - SERVER_PORT=80 - - SERVER_ROOT=/public - # NOTE: - # For the server, assets directory is not relative to root. - # That's why, it's necessary to be explicit (prefer absolute paths). - # See release v1.8.0+ for more details. - - SERVER_ASSETS=/public/assets - volumes: - - ./some-dir-path:/public - labels: - - "traefik.enable=true" - - "traefik.frontend.entryPoints=https" - - "traefik.backend=localhost_dev" - - "traefik.frontend.rule=Host:localhost.dev" - - "traefik.port=80" - networks: - - traefik_net - -networks: - traefik_net: - external: true -``` +> A blazing fast static files-serving web server. :zap: ## Contributions diff --git a/public/404.html b/public/404.html index 192df19..d339d77 100644 --- a/public/404.html +++ b/public/404.html @@ -1,33 +1,9 @@ - - - - - 404 Not Found - +404 Content was not found - -

404

-

Content was not found.

+

404 Content was not found

- diff --git a/public/50x.html b/public/50x.html index ea050e6..9a20203 100644 --- a/public/50x.html +++ b/public/50x.html @@ -1,33 +1,9 @@ - - - - - 50x Service Unavailable - +50x Service Unavailable - -

50x

-

Service is temporarily unavailable.

+

50x Service Unavailable

- diff --git a/public/index.html b/public/index.html index 41c3206..dd87f3e 100644 --- a/public/index.html +++ b/public/index.html @@ -1,21 +1,15 @@ - - - - - - Static Web Server - A blazing fast static files-serving web server powered by Rust Iron. + + + Static Web Server -

Static Web Server

-

A blazing fast static files-serving web server powered by Rust Iron.

+

A blazing fast static files-serving web server powered by Rust.

View on GitHub

- diff --git a/sample.env b/sample.env index 5b981e7..d79fcba 100644 --- a/sample.env +++ b/sample.env @@ -2,8 +2,4 @@ E_ARGS = "--port=8787" # Server configuration - SERVER_LOG_LEVEL = "trace" -SERVER_ROOT = "./public" -SERVER_ASSETS = "./public/assets" -SERVER_CORS_ALLOW_ORIGINS = "*" diff --git a/src/bin/server.rs b/src/bin/server.rs new file mode 100644 index 0000000..9e6211e --- /dev/null +++ b/src/bin/server.rs @@ -0,0 +1,36 @@ +#![deny(warnings)] + +#[cfg(all(target_env = "musl", target_pointer_width = "64"))] +#[global_allocator] +static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc; + +#[macro_use] +extern crate static_web_server; + +use self::static_web_server::{core::config, core::logger, core::rejection}; +use structopt::StructOpt; +use warp::Filter; + +/// It creates a new server instance with given options. +async fn server(opts: config::Options) { + logger::init(&opts.log_level); + + let filters = warp::get() + .and(warp::fs::dir(opts.root)) + .with(warp::compression::gzip()) + .recover(rejection::handle_rejection); + + note!("server is listening on {}:{}", &opts.host, &opts.port); + + let host = opts + .host + .parse::() + .expect("not valid IP address"); + + warp::serve(filters).run((host, opts.port)).await +} + +#[tokio::main(max_threads = 10_000)] +async fn main() { + server(config::Options::from_args()).await +} diff --git a/src/config.rs b/src/config.rs deleted file mode 100644 index a3ce7b6..0000000 --- a/src/config.rs +++ /dev/null @@ -1,56 +0,0 @@ -use structopt::StructOpt; - -/// A blazing fast static files-serving web server powered by Rust Iron -#[derive(Debug, StructOpt)] -pub struct Options { - #[structopt(long, default_value = "my-static-server", env = "SERVER_NAME")] - /// Name for server - pub name: String, - #[structopt(long, default_value = "[::]", env = "SERVER_HOST")] - /// Host address (E.g 127.0.0.1) - pub host: String, - #[structopt(long, default_value = "80", env = "SERVER_PORT")] - /// Host port - pub port: u16, - #[structopt(long, default_value = "./public", env = "SERVER_ROOT")] - /// Root directory path of static files - pub root: String, - #[structopt(long, default_value = "./public/assets", env = "SERVER_ASSETS")] - /// Assets directory path for add cache headers functionality - pub assets: String, - #[structopt( - long, - default_value = "./public/50x.html", - env = "SERVER_ERROR_PAGE_50X" - )] - /// HTML file path for 50x errors. If path is not specified or simply don't exists then server will use a generic HTML error message. - pub page50x: String, - #[structopt( - long, - default_value = "./public/404.html", - env = "SERVER_ERROR_PAGE_404" - )] - /// HTML file path for 404 errors. If path is not specified or simply don't exists then server will use a generic HTML error message. - pub page404: String, - #[structopt(long, env = "SERVER_TLS")] - /// Enables TLS/SSL support. - pub tls: bool, - #[structopt(long, default_value = "", env = "SERVER_TLS_PKCS12")] - /// A cryptographic identity PKCS #12 bundle file path containing a X509 certificate along with its corresponding private key and chain of certificates to a trusted root. - pub tls_pkcs12: String, - #[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, - #[structopt(long, default_value = "", env = "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. - pub cors_allow_origins: String, -} diff --git a/src/core/config.rs b/src/core/config.rs new file mode 100644 index 0000000..ddd1d83 --- /dev/null +++ b/src/core/config.rs @@ -0,0 +1,21 @@ +use structopt::StructOpt; + +/// Warp Web Server +#[derive(Debug, StructOpt)] +pub struct Options { + #[structopt(long, short = "s", default_value = "::", env = "SERVER_HOST")] + /// Host address (E.g 127.0.0.1 or ::1) + pub host: String, + + #[structopt(long, short = "p", default_value = "80", env = "SERVER_PORT")] + /// Host port + pub port: u16, + + #[structopt(long, short = "r", default_value = "./public", env = "SERVER_ROOT")] + /// Root directory path of static files + pub root: String, + + #[structopt(long, short = "l", default_value = "error", env = "SERVER_LOG_LEVEL")] + /// Specify a logging level in lower case. + pub log_level: String, +} diff --git a/src/core/helpers.rs b/src/core/helpers.rs new file mode 100644 index 0000000..d251a0c --- /dev/null +++ b/src/core/helpers.rs @@ -0,0 +1,35 @@ +use std::error; +use std::path::{Path, PathBuf}; + +/// Validate and return a directory path. +pub fn get_valid_dirpath>(path: P) -> Result> +where + PathBuf: From

, +{ + match PathBuf::from(path) { + v if !v.exists() => Result::Err(From::from(format!("path \"{:?}\" was not found", &v))), + v if !v.is_dir() => { + Result::Err(From::from(format!("path \"{:?}\" is not a directory", &v))) + } + v => Result::Ok(v), + } +} + +/// Get the directory name of a valid directory path. +pub fn get_dirname>(path: P) -> Result> +where + PathBuf: From

, +{ + let path = match get_valid_dirpath(path) { + Err(e) => return Result::Err(e), + Ok(v) => v, + }; + + match path.iter().last() { + Some(v) => Result::Ok(v.to_str().unwrap().to_string()), + _ => Result::Err(From::from(format!( + "directory name for path \"{:?}\" was not determined", + path, + ))), + } +} diff --git a/src/core/logger.rs b/src/core/logger.rs new file mode 100644 index 0000000..c25df23 --- /dev/null +++ b/src/core/logger.rs @@ -0,0 +1,45 @@ +use env_logger::Builder; +use log::LevelFilter; +use std::io::Write; + +/// Initialize logging builder with its levels +pub fn init(level: &str) { + let log_level = match level { + "off" => LevelFilter::Off, + "error" => LevelFilter::Error, + "warn" => LevelFilter::Warn, + "info" => LevelFilter::Info, + "debug" => LevelFilter::Debug, + "trace" => LevelFilter::Trace, + _ => { + println!("Log level \"{}\" is not supported", level); + std::process::exit(1); + } + }; + + Builder::new() + .filter_level(log_level) + .format(|buf, record| { + writeln!( + buf, + "{} [{}] - {}", + chrono::Local::now().format("%Y-%m-%dT%H:%M:%S"), + record.level(), + record.args() + ) + }) + .init(); +} + +// `note` is a custom log level macro which is not affected by env log level. +// It takes precedence over other log levels +#[macro_export] +macro_rules! note { + ($($arg:tt)*) => ({ + println!( + "{} [NOTE] - {}", + chrono::Local::now().format("%Y-%m-%dT%H:%M:%S"), + format!($($arg)*) + ); + }) +} diff --git a/src/core/mod.rs b/src/core/mod.rs new file mode 100644 index 0000000..5d48af2 --- /dev/null +++ b/src/core/mod.rs @@ -0,0 +1,7 @@ +#[macro_use] +pub mod logger; + +pub mod config; +pub mod helpers; +pub mod rejection; +pub mod signal_manager; diff --git a/src/core/rejection.rs b/src/core/rejection.rs new file mode 100644 index 0000000..f798e87 --- /dev/null +++ b/src/core/rejection.rs @@ -0,0 +1,23 @@ +use anyhow::Result; +use std::convert::Infallible; +use warp::http::StatusCode; +use warp::{Rejection, Reply}; + +// This function receives a `Rejection` and tries to return a custom +// value, otherwise simply passes the rejection along. +pub async fn handle_rejection(err: Rejection) -> Result { + let code = if err.is_not_found() { + StatusCode::NOT_FOUND + } else if let Some(_) = err.find::() { + StatusCode::BAD_REQUEST + } else if let Some(_) = err.find::() { + StatusCode::METHOD_NOT_ALLOWED + } else { + StatusCode::INTERNAL_SERVER_ERROR + }; + let body = format!( + "{}

{}

", + code, code + ); + Ok(warp::reply::with_status(warp::reply::html(body), code)) +} diff --git a/src/core/signal_manager.rs b/src/core/signal_manager.rs new file mode 100644 index 0000000..06be40c --- /dev/null +++ b/src/core/signal_manager.rs @@ -0,0 +1,56 @@ +use nix::errno::Errno; +use nix::libc::c_int; +use nix::sys::signal::{SIGCHLD, SIGINT, SIGTERM}; +use nix::sys::wait::WaitStatus::{Exited, Signaled, StillAlive}; +use nix::sys::wait::{waitpid, WaitPidFlag}; +use nix::Error; +use signal::trap::Trap; + +/// It waits for an incoming Termination Signal like Ctrl+C (SIGINT), SIGTERM, etc +pub fn wait_for_signal(f: F) +where + F: Fn(signal::Signal), +{ + let signal_trap = Trap::trap(&[SIGTERM, SIGINT, SIGCHLD]); + + for sig in signal_trap { + match sig { + SIGCHLD => { + // Current std::process::Command ip does not have a way to find + // process id, so we just wait until we have no children + loop { + match waitpid(None, Some(WaitPidFlag::WNOHANG)) { + Ok(Exited(pid, status)) => { + println!("{} exited with status {}", pid, status); + continue; + } + Ok(Signaled(pid, sig, _)) => { + println!("{} killed by {}", pid, sig as c_int); + continue; + } + Ok(StillAlive) => { + break; + } + Ok(status) => { + println!("Temporary status {:?}", status); + continue; + } + Err(Error::Sys(Errno::ECHILD)) => { + return; + } + Err(e) => { + panic!("Error {:?}", e); + } + } + } + } + + sig => f(sig), + } + } +} + +/// It casts a `signal::Signal` to `i32` +pub fn signal_to_int(sig: signal::Signal) -> i32 { + sig as c_int +} diff --git a/src/error_page.rs b/src/error_page.rs deleted file mode 100644 index 1b15877..0000000 --- a/src/error_page.rs +++ /dev/null @@ -1,80 +0,0 @@ -use iron::mime; -use iron::prelude::*; -use iron::status; -use iron::AfterMiddleware; -use std::fs; -use std::path::Path; - -const PAGE_404: &str = "

404

Content could not found

"; -const PAGE_50X: &str = - "

50x

SERVICE is temporarily unavailable due an unexpected error

"; - -/// Custom Error pages middleware for Iron -pub struct ErrorPage { - /// HTML file content for 404 errors. - pub page404: String, - /// HTML file content for 50x errors. - pub page50x: String, -} - -impl ErrorPage { - /// Create a new instance of `ErrorPage` middleware with a given html pages. - pub fn new>(page_404_path: P, page_50x_path: P) -> ErrorPage { - let page404 = if Path::new(&page_404_path.as_ref()).exists() { - fs::read_to_string(page_404_path).unwrap() - } else { - String::from(PAGE_404) - }; - - let page50x = if Path::new(&page_50x_path.as_ref()).exists() { - fs::read_to_string(page_50x_path).unwrap() - } else { - String::from(PAGE_50X) - }; - - ErrorPage { page404, page50x } - } -} - -impl AfterMiddleware for ErrorPage { - fn after(&self, req: &mut Request, resp: Response) -> IronResult { - let mut no_status_error = false; - - let content_type = "text/html" - .parse::() - .expect("Unable to create a default content type header"); - - let mut resp = match resp.status { - Some(status::NotFound) => { - Response::with((content_type, status::NotFound, self.page404.as_str())) - } - Some(status::InternalServerError) => Response::with(( - content_type, - status::InternalServerError, - self.page50x.as_str(), - )), - Some(status::BadGateway) => { - Response::with((content_type, status::BadGateway, self.page50x.as_str())) - } - Some(status::ServiceUnavailable) => Response::with(( - content_type, - status::ServiceUnavailable, - self.page50x.as_str(), - )), - Some(status::GatewayTimeout) => { - Response::with((content_type, status::GatewayTimeout, self.page50x.as_str())) - } - _ => { - no_status_error = true; - resp - } - }; - - // Empty response body only on HEAD requests and status error (404,50x) - if req.method == iron::method::Head && !no_status_error { - resp.set_mut(vec![]); - } - - Ok(resp) - } -} diff --git a/src/gzip.rs b/src/gzip.rs deleted file mode 100644 index 737c72a..0000000 --- a/src/gzip.rs +++ /dev/null @@ -1,37 +0,0 @@ -use flate2::write::GzEncoder; -use flate2::Compression; -use iron::headers::{AcceptEncoding, ContentEncoding, ContentType, Encoding}; -use iron::prelude::*; -use iron::AfterMiddleware; -use iron_staticfile_middleware::helpers; - -pub struct GzipMiddleware; - -impl AfterMiddleware for GzipMiddleware { - fn after(&self, req: &mut Request, mut resp: Response) -> IronResult { - // Skip Gzip response on HEAD requests - if req.method == iron::method::Head { - return Ok(resp); - } - - // Enable Gzip compression only for known text-based file types - let enable_gz = helpers::is_text_mime_type(resp.headers.get::()); - let accept_gz = helpers::accept_gzip(req.headers.get::()); - - if enable_gz && accept_gz { - let compressed_bytes = resp.body.as_mut().map(|b| { - let mut encoder = GzEncoder::new(vec![], Compression::fast()); - { - let _ = b.write_body(&mut encoder); - } - encoder.finish().unwrap() - }); - if let Some(b) = compressed_bytes { - resp.headers.set(ContentEncoding(vec![Encoding::Gzip])); - resp.set_mut(b); - } - } - - Ok(resp) - } -} diff --git a/src/helpers.rs b/src/helpers.rs deleted file mode 100644 index d251a0c..0000000 --- a/src/helpers.rs +++ /dev/null @@ -1,35 +0,0 @@ -use std::error; -use std::path::{Path, PathBuf}; - -/// Validate and return a directory path. -pub fn get_valid_dirpath>(path: P) -> Result> -where - PathBuf: From

, -{ - match PathBuf::from(path) { - v if !v.exists() => Result::Err(From::from(format!("path \"{:?}\" was not found", &v))), - v if !v.is_dir() => { - Result::Err(From::from(format!("path \"{:?}\" is not a directory", &v))) - } - v => Result::Ok(v), - } -} - -/// Get the directory name of a valid directory path. -pub fn get_dirname>(path: P) -> Result> -where - PathBuf: From

, -{ - let path = match get_valid_dirpath(path) { - Err(e) => return Result::Err(e), - Ok(v) => v, - }; - - match path.iter().last() { - Some(v) => Result::Ok(v.to_str().unwrap().to_string()), - _ => Result::Err(From::from(format!( - "directory name for path \"{:?}\" was not determined", - path, - ))), - } -} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..6e03bf4 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,3 @@ +extern crate anyhow; + +pub mod core; diff --git a/src/logger.rs b/src/logger.rs deleted file mode 100644 index fb6e3dc..0000000 --- a/src/logger.rs +++ /dev/null @@ -1,66 +0,0 @@ -use chrono::Local; -use env_logger::Builder; -use iron::prelude::*; -use iron::AfterMiddleware; -use log::LevelFilter; -use std::io::Write; - -/// Initialize logging builder and format -pub fn init(log_level_str: &str) { - let log_level = match log_level_str { - "off" => LevelFilter::Off, - "error" => LevelFilter::Error, - "warn" => LevelFilter::Warn, - "info" => LevelFilter::Info, - "debug" => LevelFilter::Debug, - "trace" => LevelFilter::Trace, - _ => { - println!("Log level \"{}\" is not supported", log_level_str); - std::process::exit(1); - } - }; - - Builder::new() - .filter_level(log_level) - .format(|buf, record| { - writeln!( - buf, - "{} [{}] - {}", - Local::now().format("%Y-%m-%dT%H:%M:%S"), - record.level(), - record.args() - ) - }) - .init(); -} - -/// Print specific log info for the server which doesn't depend on any level -pub fn log_server(msg: &str) { - println!( - "{} [SERVER] - {}", - Local::now().format("%Y-%m-%dT%H:%M:%S"), - &msg - ); -} - -pub struct Logger; - -impl AfterMiddleware for Logger { - fn after(&self, req: &mut Request, res: Response) -> IronResult { - info!( - "Request [{}] {} - {}", - req.method, - res.status - .into_iter() - .map(|i| i.to_string()) - .collect::(), - req.url - .path() - .into_iter() - .map(|i| format!("/{}", i)) - .collect::() - ); - - Ok(res) - } -} diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index 50cfd90..0000000 --- a/src/main.rs +++ /dev/null @@ -1,320 +0,0 @@ -#[cfg(all(target_env = "musl", target_pointer_width = "64"))] -#[global_allocator] -static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc; - -#[macro_use] -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; - -mod config; -mod error_page; -mod gzip; -mod helpers; -mod logger; -mod signal_manager; -mod staticfiles; - -/// Struct for holding a reference to a running iron server instance -#[derive(Debug)] -struct RunningServer { - listening: Listening, - server_type: String, -} - -fn on_server_running(server_name: &str, running_servers: &Vec) { - // Notify when server is running - running_servers.iter().for_each(|server| { - logger::log_server(&format!( - "{} Server \"{}\" is listening on {}", - server.server_type, server_name, server.listening.socket - )) - }); - - // Wait for incoming signals (E.g Ctrl+C (SIGINT), SIGTERM, etc - signal_manager::wait_for_signal(|sig: signal::Signal| { - let code = signal_manager::signal_to_int(sig); - - println!(); - warn!("SIGINT {} caught. HTTP Server execution exited.", code); - std::process::exit(code) - }) -} - -fn main() { - let opts = Options::from_args(); - - logger::init(&opts.log_level); - - let addr = &format!("{}{}{}", opts.host, ":", opts.port); - - // Configure & launch the HTTP server - - let files = StaticFiles::new(StaticFilesOptions { - root_dir: opts.root, - assets_dir: opts.assets, - page_50x_path: opts.page50x, - page_404_path: opts.page404, - cors_allow_origins: opts.cors_allow_origins, - }); - - let mut running_servers = Vec::new(); - if opts.tls { - // Launch static HTTPS server - let ssl = NativeTlsServer::new(opts.tls_pkcs12, &opts.tls_pkcs12_passwd).unwrap(); - - match Iron::new(files.handle()).https(addr, ssl) { - Result::Ok(listening) => running_servers.push(RunningServer { - listening, - server_type: "Static HTTPS".to_string(), - }), - 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) { - Result::Ok(listening) => running_servers.push(RunningServer { - listening, - server_type: "Static HTTP".to_string(), - }), - Result::Err(err) => panic!("{:?}", err), - } - } - on_server_running(&opts.name, &running_servers); -} - -#[cfg(test)] -mod test { - extern crate hyper; - extern crate iron_test; - extern crate tempdir; - - use super::*; - - use std::fs::{DirBuilder, File}; - use std::io::Write; - use std::path::{Path, PathBuf}; - - use self::hyper::header::Headers; - use self::iron_test::{request, response}; - use self::tempdir::TempDir; - use iron::headers::{ContentLength, ContentType}; - use iron::status; - - struct TestFilesystemSetup(TempDir); - - impl TestFilesystemSetup { - fn new() -> Self { - TestFilesystemSetup(TempDir::new("test").expect("Could not create test directory")) - } - - fn path(&self) -> &Path { - self.0.path() - } - - fn dir(&self, name: &str) -> PathBuf { - let p = self.path().join(name); - DirBuilder::new() - .recursive(true) - .create(&p) - .expect("Could not create directory"); - p - } - - fn file(&self, name: &str, body: Vec) -> PathBuf { - let p = self.path().join(name); - - let mut file = File::create(&p).expect("Could not create file"); - file.write_all(&body).expect("Could not write to file"); - - p - } - } - - #[test] - fn staticfile_allow_request_methods() { - let opts = Options::from_args(); - - let files = StaticFiles::new(StaticFilesOptions { - root_dir: opts.root, - assets_dir: opts.assets, - page_50x_path: opts.page50x, - page_404_path: opts.page404, - cors_allow_origins: "".to_string(), - }); - - let response = request::head("http://127.0.0.1/", Headers::new(), &files.handle()) - .expect("Response was a http error"); - - assert_eq!(response.status, Some(status::Ok)); - - let response = request::get("http://127.0.0.1/", Headers::new(), &files.handle()) - .expect("Response was a http error"); - - assert_eq!(response.status, Some(status::Ok)); - } - - #[test] - fn staticfile_empty_body_on_head_request() { - let opts = Options::from_args(); - - let files = StaticFiles::new(StaticFilesOptions { - root_dir: opts.root, - assets_dir: opts.assets, - page_50x_path: opts.page50x, - page_404_path: opts.page404, - cors_allow_origins: "".to_string(), - }); - - let res = request::head("http://127.0.0.1/", Headers::new(), &files.handle()) - .expect("Response was a http error"); - - assert_eq!(res.status, Some(status::Ok)); - - let result_body = response::extract_body_to_bytes(res); - assert_eq!(result_body, vec!()); - } - - #[test] - fn staticfile_valid_content_length_on_head_request() { - let root = TestFilesystemSetup::new(); - root.dir("root"); - root.file("index.html", b"

hello

".to_vec()); - - let assets = TestFilesystemSetup::new(); - assets.dir("assets"); - - let opts = Options::from_args(); - - let files = StaticFiles::new(StaticFilesOptions { - root_dir: root.path().to_str().unwrap().to_string(), - assets_dir: assets.path().to_str().unwrap().to_string(), - page_50x_path: opts.page50x, - page_404_path: opts.page404, - cors_allow_origins: "".to_string(), - }); - - let res = request::head("http://127.0.0.1/", Headers::new(), &files.handle()) - .expect("Response was a http error"); - - assert_eq!(res.status, Some(status::Ok)); - - let content_length = res.headers.get::().unwrap(); - - assert_eq!(content_length.0, 27); - } - - #[test] - fn staticfile_zero_content_length_on_404_head_request() { - let opts = Options::from_args(); - - let files = StaticFiles::new(StaticFilesOptions { - root_dir: opts.root, - assets_dir: opts.assets, - page_50x_path: opts.page50x, - page_404_path: opts.page404, - cors_allow_origins: "".to_string(), - }); - - let res = request::head("http://127.0.0.1/unknown", Headers::new(), &files.handle()) - .expect("Response was a http error"); - - assert_eq!(res.status, Some(status::NotFound)); - - let content_length = res.headers.get::().unwrap(); - - assert_eq!(content_length.0, 0); - } - - #[test] - fn staticfile_disallow_request_methods() { - let opts = Options::from_args(); - - let files = StaticFiles::new(StaticFilesOptions { - root_dir: opts.root, - assets_dir: opts.assets, - page_50x_path: opts.page50x, - page_404_path: opts.page404, - cors_allow_origins: "".to_string(), - }); - - let response = request::post("http://127.0.0.1/", Headers::new(), "", &files.handle()) - .expect("Response was a http error"); - - assert_eq!(response.status, Some(status::MethodNotAllowed)); - - let response = request::delete("http://127.0.0.1/", Headers::new(), &files.handle()) - .expect("Response was a http error"); - - assert_eq!(response.status, Some(status::MethodNotAllowed)); - - let response = request::put("http://127.0.0.1/", Headers::new(), "", &files.handle()) - .expect("Response was a http error"); - - assert_eq!(response.status, Some(status::MethodNotAllowed)); - - let response = request::patch("http://127.0.0.1/", Headers::new(), "", &files.handle()) - .expect("Response was a http error"); - - assert_eq!(response.status, Some(status::MethodNotAllowed)); - - let response = request::options("http://127.0.0.1/", Headers::new(), &files.handle()) - .expect("Response was a http error"); - - assert_eq!(response.status, Some(status::MethodNotAllowed)); - } - - #[test] - fn staticfile_valid_content_type_for_404() { - let root = TestFilesystemSetup::new(); - root.dir("root"); - - let assets = TestFilesystemSetup::new(); - assets.dir("assets"); - - let opts = Options::from_args(); - - let files = StaticFiles::new(StaticFilesOptions { - root_dir: root.path().to_str().unwrap().to_string(), - assets_dir: assets.path().to_str().unwrap().to_string(), - page_50x_path: opts.page50x, - page_404_path: opts.page404, - cors_allow_origins: "".to_string(), - }); - - let res = request::head("http://127.0.0.1/unknown", Headers::new(), &files.handle()) - .expect("Response was a http error"); - - assert_eq!(res.status, Some(status::NotFound)); - - let content_type = res.headers.get::().unwrap(); - - assert_eq!( - content_type.0, - "text/html".parse::().unwrap() - ); - } -} diff --git a/src/signal_manager.rs b/src/signal_manager.rs deleted file mode 100644 index 06be40c..0000000 --- a/src/signal_manager.rs +++ /dev/null @@ -1,56 +0,0 @@ -use nix::errno::Errno; -use nix::libc::c_int; -use nix::sys::signal::{SIGCHLD, SIGINT, SIGTERM}; -use nix::sys::wait::WaitStatus::{Exited, Signaled, StillAlive}; -use nix::sys::wait::{waitpid, WaitPidFlag}; -use nix::Error; -use signal::trap::Trap; - -/// It waits for an incoming Termination Signal like Ctrl+C (SIGINT), SIGTERM, etc -pub fn wait_for_signal(f: F) -where - F: Fn(signal::Signal), -{ - let signal_trap = Trap::trap(&[SIGTERM, SIGINT, SIGCHLD]); - - for sig in signal_trap { - match sig { - SIGCHLD => { - // Current std::process::Command ip does not have a way to find - // process id, so we just wait until we have no children - loop { - match waitpid(None, Some(WaitPidFlag::WNOHANG)) { - Ok(Exited(pid, status)) => { - println!("{} exited with status {}", pid, status); - continue; - } - Ok(Signaled(pid, sig, _)) => { - println!("{} killed by {}", pid, sig as c_int); - continue; - } - Ok(StillAlive) => { - break; - } - Ok(status) => { - println!("Temporary status {:?}", status); - continue; - } - Err(Error::Sys(Errno::ECHILD)) => { - return; - } - Err(e) => { - panic!("Error {:?}", e); - } - } - } - } - - sig => f(sig), - } - } -} - -/// It casts a `signal::Signal` to `i32` -pub fn signal_to_int(sig: signal::Signal) -> i32 { - sig as c_int -} diff --git a/src/staticfiles.rs b/src/staticfiles.rs deleted file mode 100644 index 7649ac8..0000000 --- a/src/staticfiles.rs +++ /dev/null @@ -1,100 +0,0 @@ -use crate::error_page::ErrorPage; -use crate::gzip::GzipMiddleware; -use crate::helpers; -use crate::logger::{log_server, Logger}; - -use iron::mime; -use iron::prelude::*; -use iron_cors::CorsMiddleware; -use iron_staticfile_middleware::{Cache, GuessContentType, ModifyWith, Prefix, Staticfile}; -use std::collections::HashSet; -use std::time::Duration; - -/// An Iron middleware for static files-serving. -pub struct StaticFiles { - opts: StaticFilesOptions, -} - -pub struct StaticFilesOptions { - pub root_dir: String, - pub assets_dir: String, - pub page_50x_path: String, - pub page_404_path: String, - pub cors_allow_origins: String, -} - -impl StaticFiles { - /// Create a new instance of `StaticFiles` with given options. - pub fn new(opts: StaticFilesOptions) -> StaticFiles { - StaticFiles { opts } - } - - /// Handle static files for current `StaticFiles` middleware. - pub fn handle(&self) -> Chain { - // Check the root directory - let root_dir = &match helpers::get_valid_dirpath(&self.opts.root_dir) { - Err(e) => { - error!("{}", e); - std::process::exit(1) - } - Ok(v) => v, - }; - - // Check the assets directory - let assets_dir = &match helpers::get_valid_dirpath(&self.opts.assets_dir) { - Err(e) => { - error!("{}", e); - std::process::exit(1) - } - Ok(v) => v, - }; - - // Get the assets directory name - let assets_dirname = &match helpers::get_dirname(assets_dir) { - Err(e) => { - error!("{}", e); - std::process::exit(1) - } - Ok(v) => v, - }; - - // Define middleware chain - let mut chain = Chain::new( - Staticfile::new(root_dir, assets_dir).expect("Directory to serve files was not found"), - ); - let one_day = Duration::new(60 * 60 * 24, 0); - let one_year = Duration::new(60 * 60 * 24 * 365, 0); - let default_content_type = "text/html" - .parse::() - .expect("Unable to create a default content type header"); - - // CORS support - let allowed_hosts = &self.opts.cors_allow_origins; - - if !allowed_hosts.is_empty() { - log_server("CORS enabled"); - log_server(&format!("Access-Control-Allow-Origin: {}", allowed_hosts)); - - if allowed_hosts == "*" { - chain.link_around(CorsMiddleware::with_allow_any()); - } else { - let allowed_hosts = allowed_hosts - .split(',') - .map(|s| s.to_string()) - .collect::>(); - chain.link_around(CorsMiddleware::with_whitelist(allowed_hosts)); - }; - } - - chain.link_after(ModifyWith::new(Cache::new(one_day))); - chain.link_after(Prefix::new(&[assets_dirname], Cache::new(one_year))); - chain.link_after(GuessContentType::new(default_content_type)); - chain.link_after(GzipMiddleware); - chain.link_after(Logger); - chain.link_after(ErrorPage::new( - &self.opts.page_404_path, - &self.opts.page_50x_path, - )); - chain - } -} -- libgit2 1.7.2