refactor: code base for v2
Diff
.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(-)
@@ -15,5 +15,6 @@
**/*.env
release
.vscode
TODO
!sample.env
@@ -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",
]
@@ -1,47 +1,39 @@
[package]
name = "static-web-server"
version = "1.12.0"
version = "0.0.0"
authors = ["Jose Quintana <https://git.io/joseluisq>"]
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
@@ -1,163 +1,8 @@
# Static Web Server [](https://hub.docker.com/r/joseluisq/static-web-server/) [](https://travis-ci.com/joseluisq/static-web-server) [](https://hub.docker.com/r/joseluisq/static-web-server/tags) [](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
### 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>
Assets directory path for add cache headers functionality [env: SERVER_ASSETS=] [default: ./public/assets]
--cors-allow-origins <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> Host address (E.g 127.0.0.1) [env: SERVER_HOST=] [default: [::]]
--log-level <log-level>
Specify a logging level in lower case [env: SERVER_LOG_LEVEL=] [default: error]
--name <name> Name for server [env: SERVER_NAME=] [default: my-static-server]
--page404 <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 <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 <port> Host port [env: SERVER_PORT=] [default: 80]
--root <root>
Root directory path of static files [env: SERVER_ROOT=] [default: ./public]
--tls <tls> Enables TLS/SSL support [env: SERVER_TLS=]
--tls-pkcs12 <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 <tls-pkcs12-passwd>
A specified password to decrypt the private key [env: SERVER_TLS_PKCS12_PASSWD=] [default: ]
--tls-redirect-from <tls-redirect-from>
Host port for redirecting HTTP requests to HTTPS. This option enables the HTTP redirect feature [env:
SERVER_TLS_REDIRECT_FROM=]
--tls-redirect-host <tls-redirect-host>
Host name of HTTPS site for redirecting HTTP requests to. Defaults to host address [env:
SERVER_TLS_REDIRECT_HOST=]
```
## TLS/SSL
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
@@ -1,33 +1,9 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>404 Not Found</title>
<style>
body {
font-family: sans-serif;
color: black;
text-align: center;
font-size: 1.25rem;
}
h1 a {
text-decoration: none;
color: black;
}
a {
color: #0366d6;
}
</style>
<title>404 Content was not found</title>
</head>
<body>
<h1>404</h1>
<p>Content was not found.</p>
<center><h1>404 Content was not found</h1></center>
</body>
</html>
@@ -1,33 +1,9 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>50x Service Unavailable</title>
<style>
body {
font-family: sans-serif;
color: black;
text-align: center;
font-size: 1.25rem;
}
h1 a {
text-decoration: none;
color: black;
}
a {
color: #0366d6;
}
</style>
<title>50x Service Unavailable</title>
</head>
<body>
<h1>50x</h1>
<p>Service is temporarily unavailable.</p>
<center><h1>50x Service Unavailable</h1></center>
</body>
</html>
@@ -1,21 +1,15 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Static Web Server - A blazing fast static files-serving web server powered by Rust Iron.</title>
<html>
<head>
<title>Static Web Server</title>
<link rel="stylesheet" href="/assets/main.css">
<link rel="shortcut icon" href="/assets/favicon.ico">
</head>
<body>
<h1>Static Web Server</h1>
<p>A blazing fast static files-serving web server powered by <a href="https://github.com/iron/iron"
target="_blank">Rust Iron</a>.</p>
<p>A blazing fast static files-serving web server powered by Rust.</p>
<p><a href="https://github.com/joseluisq/static-web-server/" target="_blank">View on GitHub</a></p>
<script src="/assets/main.js"></script>
</body>
</html>
@@ -2,8 +2,4 @@
E_ARGS = "--port=8787"
SERVER_LOG_LEVEL = "trace"
SERVER_ROOT = "./public"
SERVER_ASSETS = "./public/assets"
SERVER_CORS_ALLOW_ORIGINS = "*"
@@ -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;
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::<std::net::IpAddr>()
.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
}
@@ -1,56 +0,0 @@
use structopt::StructOpt;
#[derive(Debug, StructOpt)]
pub struct Options {
#[structopt(long, default_value = "my-static-server", env = "SERVER_NAME")]
pub name: String,
#[structopt(long, default_value = "[::]", env = "SERVER_HOST")]
pub host: String,
#[structopt(long, default_value = "80", env = "SERVER_PORT")]
pub port: u16,
#[structopt(long, default_value = "./public", env = "SERVER_ROOT")]
pub root: String,
#[structopt(long, default_value = "./public/assets", env = "SERVER_ASSETS")]
pub assets: String,
#[structopt(
long,
default_value = "./public/50x.html",
env = "SERVER_ERROR_PAGE_50X"
)]
pub page50x: String,
#[structopt(
long,
default_value = "./public/404.html",
env = "SERVER_ERROR_PAGE_404"
)]
pub page404: String,
#[structopt(long, env = "SERVER_TLS")]
pub tls: bool,
#[structopt(long, default_value = "", env = "SERVER_TLS_PKCS12")]
pub tls_pkcs12: String,
#[structopt(long, default_value = "", env = "SERVER_TLS_PKCS12_PASSWD")]
pub tls_pkcs12_passwd: String,
#[structopt(long, env = "SERVER_TLS_REDIRECT_FROM")]
pub tls_redirect_from: Option<u16>,
#[structopt(long, env = "SERVER_TLS_REDIRECT_HOST")]
pub tls_redirect_host: Option<String>,
#[structopt(long, default_value = "error", env = "SERVER_LOG_LEVEL")]
pub log_level: String,
#[structopt(long, default_value = "", env = "SERVER_CORS_ALLOW_ORIGINS")]
pub cors_allow_origins: String,
}
@@ -0,0 +1,21 @@
use structopt::StructOpt;
#[derive(Debug, StructOpt)]
pub struct Options {
#[structopt(long, short = "s", default_value = "::", env = "SERVER_HOST")]
pub host: String,
#[structopt(long, short = "p", default_value = "80", env = "SERVER_PORT")]
pub port: u16,
#[structopt(long, short = "r", default_value = "./public", env = "SERVER_ROOT")]
pub root: String,
#[structopt(long, short = "l", default_value = "error", env = "SERVER_LOG_LEVEL")]
pub log_level: String,
}
@@ -0,0 +1,35 @@
use std::error;
use std::path::{Path, PathBuf};
pub fn get_valid_dirpath<P: AsRef<Path>>(path: P) -> Result<PathBuf, Box<dyn error::Error>>
where
PathBuf: From<P>,
{
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),
}
}
pub fn get_dirname<P: AsRef<Path>>(path: P) -> Result<String, Box<dyn error::Error>>
where
PathBuf: From<P>,
{
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,
))),
}
}
@@ -0,0 +1,45 @@
use env_logger::Builder;
use log::LevelFilter;
use std::io::Write;
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();
}
#[macro_export]
macro_rules! note {
($($arg:tt)*) => ({
println!(
"{} [NOTE] - {}",
chrono::Local::now().format("%Y-%m-%dT%H:%M:%S"),
format!($($arg)*)
);
})
}
@@ -0,0 +1,7 @@
#[macro_use]
pub mod logger;
pub mod config;
pub mod helpers;
pub mod rejection;
pub mod signal_manager;
@@ -0,0 +1,23 @@
use anyhow::Result;
use std::convert::Infallible;
use warp::http::StatusCode;
use warp::{Rejection, Reply};
pub async fn handle_rejection(err: Rejection) -> Result<impl Reply, Infallible> {
let code = if err.is_not_found() {
StatusCode::NOT_FOUND
} else if let Some(_) = err.find::<warp::filters::body::BodyDeserializeError>() {
StatusCode::BAD_REQUEST
} else if let Some(_) = err.find::<warp::reject::MethodNotAllowed>() {
StatusCode::METHOD_NOT_ALLOWED
} else {
StatusCode::INTERNAL_SERVER_ERROR
};
let body = format!(
"<html><head><title>{}</title></head><body><center><h1>{}</h1></center></body></html>",
code, code
);
Ok(warp::reply::with_status(warp::reply::html(body), code))
}
@@ -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;
pub fn wait_for_signal<F>(f: F)
where
F: Fn(signal::Signal),
{
let signal_trap = Trap::trap(&[SIGTERM, SIGINT, SIGCHLD]);
for sig in signal_trap {
match sig {
SIGCHLD => {
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),
}
}
}
pub fn signal_to_int(sig: signal::Signal) -> i32 {
sig as c_int
}
@@ -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 = "<h2>404</h2><p>Content could not found</p>";
const PAGE_50X: &str =
"<h2>50x</h2><p>SERVICE is temporarily unavailable due an unexpected error</p>";
pub struct ErrorPage {
pub page404: String,
pub page50x: String,
}
impl ErrorPage {
pub fn new<P: AsRef<Path>>(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<Response> {
let mut no_status_error = false;
let content_type = "text/html"
.parse::<mime::Mime>()
.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
}
};
if req.method == iron::method::Head && !no_status_error {
resp.set_mut(vec![]);
}
Ok(resp)
}
}
@@ -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<Response> {
if req.method == iron::method::Head {
return Ok(resp);
}
let enable_gz = helpers::is_text_mime_type(resp.headers.get::<ContentType>());
let accept_gz = helpers::accept_gzip(req.headers.get::<AcceptEncoding>());
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)
}
}
@@ -1,35 +0,0 @@
use std::error;
use std::path::{Path, PathBuf};
pub fn get_valid_dirpath<P: AsRef<Path>>(path: P) -> Result<PathBuf, Box<dyn error::Error>>
where
PathBuf: From<P>,
{
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),
}
}
pub fn get_dirname<P: AsRef<Path>>(path: P) -> Result<String, Box<dyn error::Error>>
where
PathBuf: From<P>,
{
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,
))),
}
}
@@ -0,0 +1,3 @@
extern crate anyhow;
pub mod core;
@@ -1,66 +0,0 @@
use chrono::Local;
use env_logger::Builder;
use iron::prelude::*;
use iron::AfterMiddleware;
use log::LevelFilter;
use std::io::Write;
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();
}
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<Response> {
info!(
"Request [{}] {} - {}",
req.method,
res.status
.into_iter()
.map(|i| i.to_string())
.collect::<String>(),
req.url
.path()
.into_iter()
.map(|i| format!("/{}", i))
.collect::<String>()
);
Ok(res)
}
}
@@ -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;
#[derive(Debug)]
struct RunningServer {
listening: Listening,
server_type: String,
}
fn on_server_running(server_name: &str, running_servers: &Vec<RunningServer>) {
running_servers.iter().for_each(|server| {
logger::log_server(&format!(
"{} Server \"{}\" is listening on {}",
server.server_type, server_name, server.listening.socket
))
});
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);
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 {
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),
}
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 {
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<u8>) -> 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"<html><h2>hello</h2></html>".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::<ContentLength>().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::<ContentLength>().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::<ContentType>().unwrap();
assert_eq!(
content_type.0,
"text/html".parse::<iron::mime::Mime>().unwrap()
);
}
}
@@ -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;
pub fn wait_for_signal<F>(f: F)
where
F: Fn(signal::Signal),
{
let signal_trap = Trap::trap(&[SIGTERM, SIGINT, SIGCHLD]);
for sig in signal_trap {
match sig {
SIGCHLD => {
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),
}
}
}
pub fn signal_to_int(sig: signal::Signal) -> i32 {
sig as c_int
}
@@ -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;
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 {
pub fn new(opts: StaticFilesOptions) -> StaticFiles {
StaticFiles { opts }
}
pub fn handle(&self) -> Chain {
let root_dir = &match helpers::get_valid_dirpath(&self.opts.root_dir) {
Err(e) => {
error!("{}", e);
std::process::exit(1)
}
Ok(v) => v,
};
let assets_dir = &match helpers::get_valid_dirpath(&self.opts.assets_dir) {
Err(e) => {
error!("{}", e);
std::process::exit(1)
}
Ok(v) => v,
};
let assets_dirname = &match helpers::get_dirname(assets_dir) {
Err(e) => {
error!("{}", e);
std::process::exit(1)
}
Ok(v) => v,
};
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::<mime::Mime>()
.expect("Unable to create a default content type header");
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::<HashSet<_>>();
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
}
}