From 88509d4fcc8ad2a9d666b37747a2f6909b97c63e Mon Sep 17 00:00:00 2001
From: Eduardo Trujillo <ed@chromabits.com>
Date: Mon, 14 Nov 2022 21:27:04 -0800
Subject: [PATCH] refactor: Upgrade to support actix-web 4.x

---
 Cargo.lock                | 2848 ++++++++++++++++++++++++-------------
 Cargo.toml                |   41 +-
 src/bundle/s3/packager.rs |    2 +-
 src/bundle/s3/poller.rs   |   17 +-
 src/files/chunked.rs      |   98 --
 src/files/mod.rs          | 1469 +++++++++----------
 src/files/named.rs        |  451 ------
 src/files/named_ext.rs    |   29 +
 src/files/path_context.rs |    5 +-
 src/files/pathbuf.rs      |    1 -
 src/files/range.rs        |  406 ------
 src/files/service.rs      |  346 ++---
 src/main.rs               |   18 +-
 src/server.rs             |   35 +-
 src/stats.rs              |   31 +-
 15 files changed, 2873 insertions(+), 2924 deletions(-)
 delete mode 100644 src/files/chunked.rs
 delete mode 100644 src/files/named.rs
 create mode 100644 src/files/named_ext.rs
 delete mode 100644 src/files/range.rs

diff --git a/Cargo.lock b/Cargo.lock
index ae06f60..800f412 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1,28 +1,29 @@
 # This file is automatically @generated by Cargo.
 # It is not intended for manual editing.
+version = 3
+
 [[package]]
 name = "actix"
-version = "0.9.0"
+version = "0.13.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a4af87564ff659dee8f9981540cac9418c45e910c8072fdedd643a262a38fcaf"
+checksum = "f728064aca1c318585bf4bb04ffcfac9e75e508ab4e8b1bd9ba5dfe04e2cbed5"
 dependencies = [
- "actix-http",
- "actix-rt",
+ "actix-rt 2.7.0",
  "actix_derive",
  "bitflags",
- "bytes",
+ "bytes 1.2.1",
  "crossbeam-channel",
- "derive_more",
- "futures",
- "lazy_static",
+ "futures-core",
+ "futures-sink",
+ "futures-task",
+ "futures-util",
  "log",
- "parking_lot 0.10.2",
- "pin-project",
+ "once_cell",
+ "parking_lot 0.12.1",
+ "pin-project-lite 0.2.9",
  "smallvec",
- "tokio",
- "tokio-util 0.2.0",
- "trust-dns-proto",
- "trust-dns-resolver",
+ "tokio 1.21.2",
+ "tokio-util 0.7.4",
 ]
 
 [[package]]
@@ -32,24 +33,41 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "09e55f0a5c2ca15795035d90c46bd0e73a5123b72f68f12596d6ba5282051380"
 dependencies = [
  "bitflags",
- "bytes",
+ "bytes 0.5.6",
  "futures-core",
  "futures-sink",
  "log",
- "tokio",
+ "tokio 0.2.25",
  "tokio-util 0.2.0",
 ]
 
+[[package]]
+name = "actix-codec"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "57a7559404a7f3573127aab53c08ce37a6c6a315c374a31070f3c91cd1b4a7fe"
+dependencies = [
+ "bitflags",
+ "bytes 1.2.1",
+ "futures-core",
+ "futures-sink",
+ "log",
+ "memchr",
+ "pin-project-lite 0.2.9",
+ "tokio 1.21.2",
+ "tokio-util 0.7.4",
+]
+
 [[package]]
 name = "actix-connect"
 version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c95cc9569221e9802bf4c377f6c18b90ef10227d787611decf79fd47d2a8e76c"
 dependencies = [
- "actix-codec",
- "actix-rt",
- "actix-service",
- "actix-utils",
+ "actix-codec 0.2.0",
+ "actix-rt 1.1.1",
+ "actix-service 1.0.6",
+ "actix-utils 1.0.6",
  "derive_more",
  "either",
  "futures",
@@ -59,58 +77,125 @@ dependencies = [
  "trust-dns-resolver",
 ]
 
+[[package]]
+name = "actix-files"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d832782fac6ca7369a70c9ee9a20554623c5e51c76e190ad151780ebea1cf689"
+dependencies = [
+ "actix-http 3.2.2",
+ "actix-service 2.0.2",
+ "actix-utils 3.0.1",
+ "actix-web",
+ "askama_escape",
+ "bitflags",
+ "bytes 1.2.1",
+ "derive_more",
+ "futures-core",
+ "http-range",
+ "log",
+ "mime",
+ "mime_guess",
+ "percent-encoding",
+ "pin-project-lite 0.2.9",
+]
+
 [[package]]
 name = "actix-http"
 version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c16664cc4fdea8030837ad5a845eb231fb93fc3c5c171edfefb52fad92ce9019"
 dependencies = [
- "actix-codec",
+ "actix-codec 0.2.0",
  "actix-connect",
- "actix-rt",
- "actix-service",
+ "actix-rt 1.1.1",
+ "actix-service 1.0.6",
  "actix-threadpool",
- "actix-utils",
+ "actix-utils 1.0.6",
  "base64 0.11.0",
  "bitflags",
- "brotli2",
- "bytes",
+ "bytes 0.5.6",
  "chrono",
  "copyless",
  "derive_more",
  "either",
  "encoding_rs",
- "failure",
- "flate2",
  "futures-channel",
  "futures-core",
  "futures-util",
  "fxhash",
- "h2",
+ "h2 0.2.7",
  "http",
  "httparse",
  "indexmap",
- "language-tags",
+ "language-tags 0.2.2",
  "lazy_static",
  "log",
  "mime",
  "percent-encoding",
- "pin-project",
- "rand",
+ "pin-project 0.4.30",
+ "rand 0.7.3",
  "regex",
  "serde",
  "serde_json",
- "serde_urlencoded",
- "sha1",
+ "serde_urlencoded 0.6.1",
+ "sha1 0.6.1",
  "slab",
- "time 0.1.43",
+ "time 0.1.44",
+]
+
+[[package]]
+name = "actix-http"
+version = "3.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0c83abf9903e1f0ad9973cc4f7b9767fd5a03a583f51a5b7a339e07987cd2724"
+dependencies = [
+ "actix-codec 0.5.0",
+ "actix-rt 2.7.0",
+ "actix-service 2.0.2",
+ "actix-utils 3.0.1",
+ "ahash",
+ "base64 0.13.1",
+ "bitflags",
+ "brotli",
+ "bytes 1.2.1",
+ "bytestring",
+ "derive_more",
+ "encoding_rs",
+ "flate2",
+ "futures-core",
+ "h2 0.3.15",
+ "http",
+ "httparse",
+ "httpdate",
+ "itoa 1.0.4",
+ "language-tags 0.3.2",
+ "local-channel",
+ "mime",
+ "percent-encoding",
+ "pin-project-lite 0.2.9",
+ "rand 0.8.5",
+ "sha1 0.10.5",
+ "smallvec",
+ "tracing",
+ "zstd",
 ]
 
 [[package]]
 name = "actix-macros"
-version = "0.1.2"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b4ca8ce00b267af8ccebbd647de0d61e0674b6e61185cc7a592ff88772bed655"
+dependencies = [
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "actix-macros"
+version = "0.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a60f9ba7c4e6df97f3aacb14bb5c0cd7d98a49dcbaed0d7f292912ad9a6a3ed2"
+checksum = "465a6172cf69b960917811022d8f29bc0b7fa1398bc4f78b3c466673db1213b6"
 dependencies = [
  "quote",
  "syn",
@@ -118,15 +203,15 @@ dependencies = [
 
 [[package]]
 name = "actix-router"
-version = "0.2.4"
+version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d7a10ca4d94e8c8e7a87c5173aba1b97ba9a6563ca02b0e1cd23531093d3ec8"
+checksum = "d66ff4d247d2b160861fa2866457e85706833527840e4133f8f49aa423a38799"
 dependencies = [
  "bytestring",
  "http",
- "log",
  "regex",
  "serde",
+ "tracing",
 ]
 
 [[package]]
@@ -135,33 +220,42 @@ version = "1.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "143fcc2912e0d1de2bcf4e2f720d2a60c28652ab4179685a1ee159e0fb3db227"
 dependencies = [
- "actix-macros",
+ "actix-macros 0.1.3",
  "actix-threadpool",
  "copyless",
  "futures-channel",
  "futures-util",
  "smallvec",
- "tokio",
+ "tokio 0.2.25",
+]
+
+[[package]]
+name = "actix-rt"
+version = "2.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7ea16c295198e958ef31930a6ef37d0fb64e9ca3b6116e6b93a8bdae96ee1000"
+dependencies = [
+ "actix-macros 0.2.3",
+ "futures-core",
+ "tokio 1.21.2",
 ]
 
 [[package]]
 name = "actix-server"
-version = "1.0.3"
+version = "2.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e6d74b464215a473c973a2d7d03a69cc10f4ce1f4b38a7659c5193dc5c675630"
+checksum = "0da34f8e659ea1b077bb4637948b815cd3768ad5a188fdcd74ff4d84240cd824"
 dependencies = [
- "actix-codec",
- "actix-rt",
- "actix-service",
- "actix-utils",
- "futures-channel",
+ "actix-rt 2.7.0",
+ "actix-service 2.0.2",
+ "actix-utils 3.0.1",
+ "futures-core",
  "futures-util",
- "log",
- "mio",
- "mio-uds",
+ "mio 0.8.5",
  "num_cpus",
- "slab",
- "socket2",
+ "socket2 0.4.7",
+ "tokio 1.21.2",
+ "tracing",
 ]
 
 [[package]]
@@ -171,21 +265,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0052435d581b5be835d11f4eb3bce417c8af18d87ddf8ace99f8e67e595882bb"
 dependencies = [
  "futures-util",
- "pin-project",
+ "pin-project 0.4.30",
 ]
 
 [[package]]
-name = "actix-testing"
-version = "1.0.1"
+name = "actix-service"
+version = "2.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "47239ca38799ab74ee6a8a94d1ce857014b2ac36f242f70f3f75a66f691e791c"
+checksum = "3b894941f818cfdc7ccc4b9e60fa7e53b5042a2e8567270f9147d5591893373a"
 dependencies = [
- "actix-macros",
- "actix-rt",
- "actix-server",
- "actix-service",
- "log",
- "socket2",
+ "futures-core",
+ "paste",
+ "pin-project-lite 0.2.9",
 ]
 
 [[package]]
@@ -199,86 +290,86 @@ dependencies = [
  "lazy_static",
  "log",
  "num_cpus",
- "parking_lot 0.11.0",
+ "parking_lot 0.11.2",
  "threadpool",
 ]
 
 [[package]]
-name = "actix-tls"
-version = "1.0.0"
+name = "actix-utils"
+version = "1.0.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a4e5b4faaf105e9a6d389c606c298dcdb033061b00d532af9df56ff3a54995a8"
+checksum = "fcf8f5631bf01adec2267808f00e228b761c60c0584cc9fa0b5364f41d147f4e"
 dependencies = [
- "actix-codec",
- "actix-rt",
- "actix-service",
- "actix-utils",
- "derive_more",
+ "actix-codec 0.2.0",
+ "actix-rt 1.1.1",
+ "actix-service 1.0.6",
+ "bitflags",
+ "bytes 0.5.6",
  "either",
  "futures",
  "log",
+ "pin-project 0.4.30",
+ "slab",
 ]
 
 [[package]]
 name = "actix-utils"
-version = "1.0.6"
+version = "3.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fcf8f5631bf01adec2267808f00e228b761c60c0584cc9fa0b5364f41d147f4e"
+checksum = "88a1dcdff1466e3c2488e1cb5c36a71822750ad43839937f85d2f4d9f8b705d8"
 dependencies = [
- "actix-codec",
- "actix-rt",
- "actix-service",
- "bitflags",
- "bytes",
- "either",
- "futures",
- "log",
- "pin-project",
- "slab",
+ "local-waker",
+ "pin-project-lite 0.2.9",
 ]
 
 [[package]]
 name = "actix-web"
-version = "2.0.0"
+version = "4.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3158e822461040822f0dbf1735b9c2ce1f95f93b651d7a7aded00b1efbb1f635"
+checksum = "d48f7b6534e06c7bfc72ee91db7917d4af6afe23e7d223b51e68fffbb21e96b9"
 dependencies = [
- "actix-codec",
- "actix-http",
- "actix-macros",
+ "actix-codec 0.5.0",
+ "actix-http 3.2.2",
+ "actix-macros 0.2.3",
  "actix-router",
- "actix-rt",
+ "actix-rt 2.7.0",
  "actix-server",
- "actix-service",
- "actix-testing",
- "actix-threadpool",
- "actix-tls",
- "actix-utils",
+ "actix-service 2.0.2",
+ "actix-utils 3.0.1",
  "actix-web-codegen",
- "awc",
- "bytes",
+ "ahash",
+ "bytes 1.2.1",
+ "bytestring",
+ "cfg-if 1.0.0",
+ "cookie",
  "derive_more",
  "encoding_rs",
- "futures",
- "fxhash",
+ "futures-core",
+ "futures-util",
+ "http",
+ "itoa 1.0.4",
+ "language-tags 0.3.2",
  "log",
  "mime",
- "net2",
- "pin-project",
+ "once_cell",
+ "pin-project-lite 0.2.9",
  "regex",
  "serde",
  "serde_json",
- "serde_urlencoded",
- "time 0.1.43",
+ "serde_urlencoded 0.7.1",
+ "smallvec",
+ "socket2 0.4.7",
+ "time 0.3.17",
  "url",
 ]
 
 [[package]]
 name = "actix-web-codegen"
-version = "0.2.2"
+version = "4.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a71bf475cbe07281d0b3696abb48212db118e7e23219f13596ce865235ff5766"
+checksum = "1fa9362663c8643d67b2d5eafba49e4cb2c8a053a29ed00a0bea121f17c76b13"
 dependencies = [
+ "actix-router",
  "proc-macro2",
  "quote",
  "syn",
@@ -286,9 +377,9 @@ dependencies = [
 
 [[package]]
 name = "actix_derive"
-version = "0.5.0"
+version = "0.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b95aceadaf327f18f0df5962fedc1bde2f870566a0b9f65c89508a3b1f79334c"
+checksum = "6d44b8fee1ced9671ba043476deddef739dd0959bf77030b26b738cc591737a7"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -297,190 +388,269 @@ dependencies = [
 
 [[package]]
 name = "addr2line"
-version = "0.13.0"
+version = "0.17.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b6a2d3371669ab3ca9797670853d61402b03d0b4b9ebf33d677dfa720203072"
+checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b"
 dependencies = [
  "gimli",
 ]
 
 [[package]]
 name = "adler"
-version = "0.2.3"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
+
+[[package]]
+name = "ahash"
+version = "0.7.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e"
+checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
+dependencies = [
+ "getrandom 0.2.8",
+ "once_cell",
+ "version_check",
+]
 
 [[package]]
 name = "aho-corasick"
-version = "0.7.13"
+version = "0.7.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "043164d8ba5c4c3035fec9bbee8647c0261d788f3474306f93bb65901cae0e86"
+checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e"
 dependencies = [
  "memchr",
 ]
 
 [[package]]
-name = "anyhow"
-version = "1.0.32"
+name = "alloc-no-stdlib"
+version = "2.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6b602bfe940d21c130f3895acd65221e8a61270debe89d628b9cb4e3ccb8569b"
+checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3"
 
 [[package]]
-name = "arc-swap"
-version = "0.4.7"
+name = "alloc-stdlib"
+version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4d25d88fd6b8041580a654f9d0c581a047baee2b3efee13275f2fc392fc75034"
+checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece"
+dependencies = [
+ "alloc-no-stdlib",
+]
 
 [[package]]
-name = "arrayref"
-version = "0.3.6"
+name = "android_system_properties"
+version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
+checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
+dependencies = [
+ "libc",
+]
 
 [[package]]
-name = "arrayvec"
-version = "0.5.1"
+name = "anyhow"
+version = "1.0.66"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6"
+
+[[package]]
+name = "askama_escape"
+version = "0.10.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8"
+checksum = "619743e34b5ba4e9703bba34deac3427c72507c7159f5fd030aea8cac0cfe341"
 
 [[package]]
 name = "async-channel"
-version = "1.4.2"
+version = "1.7.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "21279cfaa4f47df10b1816007e738ca3747ef2ee53ffc51cdbf57a8bb266fee3"
+checksum = "e14485364214912d3b19cc3435dde4df66065127f05fa0d75c712f36f12c2f28"
 dependencies = [
- "concurrent-queue",
+ "concurrent-queue 1.2.4",
  "event-listener",
  "futures-core",
 ]
 
 [[package]]
 name = "async-compat"
-version = "0.1.3"
+version = "0.1.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4316ce79a7185ddb5cbb692bc5e992e3bbdb68a00382fa0b0ee248f05c16ecd7"
+checksum = "3f0bb3019d8e5ffe88594b122ba9ba37280a3bc8d94a742b56c8417457215ae4"
 dependencies = [
  "futures-core",
  "futures-io",
  "once_cell",
- "pin-project-lite 0.1.7",
- "tokio",
+ "pin-project-lite 0.1.12",
+ "tokio 0.2.25",
 ]
 
 [[package]]
 name = "async-compression"
-version = "0.3.7"
+version = "0.3.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b72c1f1154e234325b50864a349b9c8e56939e266a4c307c0f159812df2f9537"
+checksum = "942c7cd7ae39e91bde4820d74132e9862e62c2f386c3aa90ccf55949f5bad63a"
 dependencies = [
  "flate2",
  "futures-core",
  "memchr",
- "pin-project-lite 0.2.0",
- "tokio",
+ "pin-project-lite 0.2.9",
+ "tokio 1.21.2",
 ]
 
 [[package]]
 name = "async-executor"
-version = "0.1.2"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "17adb73da160dfb475c183343c8cccd80721ea5a605d3eb57125f0a7b7a92d0b"
+dependencies = [
+ "async-lock",
+ "async-task",
+ "concurrent-queue 2.0.0",
+ "fastrand",
+ "futures-lite",
+ "slab",
+]
+
+[[package]]
+name = "async-global-executor"
+version = "2.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "90f47c78ea98277cb1f5e6f60ba4fc762f5eafe9f6511bc2f7dfd8b75c225650"
+checksum = "f1b6f5d7df27bd294849f8eec66ecfc63d11814df7a4f5d74168a2394467b776"
 dependencies = [
+ "async-channel",
+ "async-executor",
  "async-io",
+ "async-lock",
+ "blocking",
  "futures-lite",
- "multitask",
- "parking 1.0.6",
- "scoped-tls",
- "waker-fn",
+ "once_cell",
 ]
 
 [[package]]
 name = "async-io"
-version = "0.1.11"
+version = "1.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3ae22a338d28c75b53702b66f77979062cb29675db376d99e451af4fa79dedb3"
+checksum = "e8121296a9f05be7f34aa4196b1747243b3b62e048bb7906f644f3fbfc490cf7"
 dependencies = [
- "cfg-if",
- "concurrent-queue",
+ "async-lock",
+ "autocfg",
+ "concurrent-queue 1.2.4",
  "futures-lite",
  "libc",
- "once_cell",
- "parking 2.0.0",
+ "log",
+ "parking",
  "polling",
- "socket2",
- "vec-arena",
- "wepoll-sys-stjepang",
+ "slab",
+ "socket2 0.4.7",
+ "waker-fn",
  "winapi 0.3.9",
 ]
 
 [[package]]
-name = "async-mutex"
-version = "1.3.0"
+name = "async-lock"
+version = "2.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "66941c2577c4fa351e4ce5fdde8f86c69b88d623f3b955be1bc7362a23434632"
+checksum = "c8101efe8695a6c17e02911402145357e718ac92d3ff88ae8419e84b1707b685"
 dependencies = [
  "event-listener",
+ "futures-lite",
+]
+
+[[package]]
+name = "async-recursion"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2cda8f4bcc10624c4e85bc66b3f452cca98cfa5ca002dc83a16aad2367641bea"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
 ]
 
 [[package]]
 name = "async-std"
-version = "1.6.3"
+version = "1.12.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "46c8da367da62b8ff2313c406c9ac091c1b31d67a165becdd2de380d846260f7"
+checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d"
 dependencies = [
- "async-executor",
+ "async-channel",
+ "async-global-executor",
  "async-io",
- "async-mutex",
- "async-task",
- "blocking",
+ "async-lock",
  "crossbeam-utils",
  "futures-channel",
  "futures-core",
  "futures-io",
  "futures-lite",
- "futures-timer",
+ "gloo-timers",
  "kv-log-macro",
  "log",
  "memchr",
- "num_cpus",
  "once_cell",
- "pin-project-lite 0.1.7",
+ "pin-project-lite 0.2.9",
  "pin-utils",
  "slab",
  "wasm-bindgen-futures",
 ]
 
+[[package]]
+name = "async-stream"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dad5c83079eae9969be7fadefe640a1c566901f05ff91ab221de4b6f68d9507e"
+dependencies = [
+ "async-stream-impl",
+ "futures-core",
+]
+
+[[package]]
+name = "async-stream-impl"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "10f203db73a71dfa2fb6dd22763990fa26f3d2625a6da2da900d23b87d26be27"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
 [[package]]
 name = "async-tar"
-version = "0.3.0"
+version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cb619eae01ab289095debb1ff7c02710d5124c20edde1b2eca926572a34c3998"
+checksum = "5c49359998a76e32ef6e870dbc079ebad8f1e53e8441c5dd39d27b44493fe331"
 dependencies = [
  "async-std",
  "filetime",
  "libc",
- "pin-project",
+ "pin-project 1.0.12",
  "redox_syscall",
  "xattr",
 ]
 
 [[package]]
 name = "async-task"
-version = "3.0.0"
+version = "4.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c17772156ef2829aadc587461c7753af20b7e8db1529bc66855add962a3b35d3"
+checksum = "7a40729d2133846d9ed0ea60a8b9541bccddab49cd30f0715a1da672fe9a2524"
 
 [[package]]
 name = "async-trait"
-version = "0.1.40"
+version = "0.1.58"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "687c230d85c0a52504709705fc8a53e4a692b83a2184f03dae73e38e1e93a783"
+checksum = "1e805d94e6b5001b651426cf4cd446b1ab5f319d27bab5c644f61de0a804360c"
 dependencies = [
  "proc-macro2",
  "quote",
  "syn",
 ]
 
+[[package]]
+name = "atomic"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b88d82667eca772c4aa12f0f1348b3ae643424c8876448f3f7bd5787032e234c"
+dependencies = [
+ "autocfg",
+]
+
 [[package]]
 name = "atomic-waker"
 version = "1.0.0"
@@ -500,53 +670,70 @@ dependencies = [
 
 [[package]]
 name = "autocfg"
-version = "1.0.0"
+version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
+checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
 
 [[package]]
-name = "awc"
-version = "1.0.1"
+name = "axum"
+version = "0.5.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d7601d4d1d7ef2335d6597a41b5fe069f6ab799b85f53565ab390e7b7065aac5"
+checksum = "acee9fd5073ab6b045a275b3e709c163dd36c90685219cb21804a147b58dba43"
 dependencies = [
- "actix-codec",
- "actix-http",
- "actix-rt",
- "actix-service",
- "base64 0.11.0",
- "bytes",
- "derive_more",
- "futures-core",
- "log",
+ "async-trait",
+ "axum-core",
+ "bitflags",
+ "bytes 1.2.1",
+ "futures-util",
+ "http",
+ "http-body",
+ "hyper",
+ "itoa 1.0.4",
+ "matchit",
+ "memchr",
  "mime",
  "percent-encoding",
- "rand",
+ "pin-project-lite 0.2.9",
  "serde",
- "serde_json",
- "serde_urlencoded",
+ "sync_wrapper",
+ "tokio 1.21.2",
+ "tower",
+ "tower-http",
+ "tower-layer",
+ "tower-service",
+]
+
+[[package]]
+name = "axum-core"
+version = "0.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "37e5939e02c56fecd5c017c37df4238c0a839fa76b7f97acdd7efb804fd181cc"
+dependencies = [
+ "async-trait",
+ "bytes 1.2.1",
+ "futures-util",
+ "http",
+ "http-body",
+ "mime",
+ "tower-layer",
+ "tower-service",
 ]
 
 [[package]]
 name = "backtrace"
-version = "0.3.50"
+version = "0.3.66"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "46254cf2fdcdf1badb5934448c1bcbe046a56537b3987d96c51a7afc5d03f293"
+checksum = "cab84319d616cfb654d03394f38ab7e6f0919e181b1b57e1fd15e7fb4077d9a7"
 dependencies = [
  "addr2line",
- "cfg-if",
+ "cc",
+ "cfg-if 1.0.0",
  "libc",
  "miniz_oxide",
  "object",
  "rustc-demangle",
 ]
 
-[[package]]
-name = "base-x"
-version = "0.2.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b20b618342cf9891c292c4f5ac2cde7287cc5c87e87e9c769d617793607dec1"
-
 [[package]]
 name = "base64"
 version = "0.11.0"
@@ -555,107 +742,80 @@ checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
 
 [[package]]
 name = "base64"
-version = "0.12.3"
+version = "0.13.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff"
+checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
 
 [[package]]
 name = "bitflags"
-version = "1.2.1"
+version = "1.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
 
 [[package]]
-name = "blake2b_simd"
-version = "0.5.10"
+name = "block-buffer"
+version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a"
+checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
 dependencies = [
- "arrayref",
- "arrayvec",
- "constant_time_eq",
+ "generic-array",
 ]
 
 [[package]]
 name = "block-buffer"
-version = "0.7.3"
+version = "0.10.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
+checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e"
 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",
+ "generic-array",
 ]
 
 [[package]]
 name = "blocking"
-version = "0.5.2"
+version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ea5800d29218fea137b0880387e5948694a23c93fcdde157006966693a865c7c"
+checksum = "c6ccb65d468978a086b69884437ded69a90faab3bbe6e67f242173ea728acccc"
 dependencies = [
  "async-channel",
+ "async-task",
  "atomic-waker",
+ "fastrand",
  "futures-lite",
  "once_cell",
- "waker-fn",
 ]
 
 [[package]]
-name = "brotli-sys"
-version = "0.3.2"
+name = "brotli"
+version = "3.3.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4445dea95f4c2b41cde57cc9fee236ae4dbae88d8fcbdb4750fc1bb5d86aaecd"
+checksum = "a1a0b1dbcc8ae29329621f8d4f0d835787c1c38bb1401979b49d13b0b305ff68"
 dependencies = [
- "cc",
- "libc",
+ "alloc-no-stdlib",
+ "alloc-stdlib",
+ "brotli-decompressor",
 ]
 
 [[package]]
-name = "brotli2"
-version = "0.3.2"
+name = "brotli-decompressor"
+version = "2.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0cb036c3eade309815c15ddbacec5b22c4d1f3983a774ab2eac2e3e9ea85568e"
+checksum = "59ad2d4653bf5ca36ae797b1f4bb4dbddb60ce49ca4aed8a2ce4829f60425b80"
 dependencies = [
- "brotli-sys",
- "libc",
+ "alloc-no-stdlib",
+ "alloc-stdlib",
 ]
 
 [[package]]
 name = "bumpalo"
-version = "3.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820"
-
-[[package]]
-name = "byte-tools"
-version = "0.3.1"
+version = "3.11.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
+checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba"
 
 [[package]]
 name = "byteorder"
-version = "1.3.4"
+version = "1.4.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
+checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
 
 [[package]]
 name = "bytes"
@@ -663,26 +823,35 @@ version = "0.5.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38"
 
+[[package]]
+name = "bytes"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db"
+
 [[package]]
 name = "bytestring"
-version = "0.1.5"
+version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc7c05fa5172da78a62d9949d662d2ac89d4cc7355d7b49adee5163f1fb3f363"
+checksum = "f7f83e57d9154148e355404702e2694463241880b939570d7c97c014da7a69a1"
 dependencies = [
- "bytes",
+ "bytes 1.2.1",
 ]
 
 [[package]]
 name = "cache-padded"
-version = "1.1.1"
+version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "631ae5198c9be5e753e5cc215e1bd73c2b466a3565173db433f52bb9d3e66dba"
+checksum = "c1db59621ec70f09c5e9b597b220c7a2b43611f4710dc03ceb8748637775692c"
 
 [[package]]
 name = "cc"
-version = "1.0.58"
+version = "1.0.76"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f9a06fb2e53271d7c279ec1efea6ab691c35a2ae67ec0d91d7acec0caf13b518"
+checksum = "76a284da2e6fe2092f2353e51713435363112dfd60030e22add80be333fb928f"
+dependencies = [
+ "jobserver",
+]
 
 [[package]]
 name = "cfg-if"
@@ -690,42 +859,50 @@ version = "0.1.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
 
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
 [[package]]
 name = "chrono"
-version = "0.4.15"
+version = "0.4.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "942f72db697d8767c22d46a598e01f2d3b475501ea43d0db4f16d90259182d0b"
+checksum = "bfd4d1b31faaa3a89d7934dbded3111da0d2ef28e3ebccdb4f0179f5929d1ef1"
 dependencies = [
+ "iana-time-zone",
+ "js-sys",
  "num-integer",
  "num-traits",
  "serde",
- "time 0.1.43",
+ "time 0.1.44",
+ "wasm-bindgen",
+ "winapi 0.3.9",
 ]
 
 [[package]]
 name = "clap"
-version = "3.0.0-beta.2"
+version = "3.2.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4bd1061998a501ee7d4b6d449020df3266ca3124b941ec56cf2005c3779ca142"
+checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5"
 dependencies = [
  "atty",
  "bitflags",
  "clap_derive",
+ "clap_lex",
  "indexmap",
- "lazy_static",
- "os_str_bytes",
+ "once_cell",
  "strsim",
  "termcolor",
  "textwrap",
- "unicode-width",
- "vec_map",
 ]
 
 [[package]]
 name = "clap_derive"
-version = "3.0.0-beta.2"
+version = "3.2.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "370f715b81112975b1b69db93e0b56ea4cd4e5002ac43b2da8474106a54096a1"
+checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65"
 dependencies = [
  "heck",
  "proc-macro-error",
@@ -735,51 +912,110 @@ dependencies = [
 ]
 
 [[package]]
-name = "cloudabi"
-version = "0.0.3"
+name = "clap_lex"
+version = "0.2.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
+checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5"
 dependencies = [
- "bitflags",
+ "os_str_bytes",
 ]
 
 [[package]]
-name = "cloudabi"
-version = "0.1.0"
+name = "codespan-reporting"
+version = "0.11.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4344512281c643ae7638bbabc3af17a11307803ec8f0fcad9fae512a8bf36467"
+checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e"
 dependencies = [
- "bitflags",
+ "termcolor",
+ "unicode-width",
 ]
 
 [[package]]
 name = "collective"
 version = "0.1.2"
-source = "git+https://gitlab.chromabits.com/etcinit/collective.git?tag=0.1.2#137121204a41de9ef30b4c458b041ac680c308e8"
+source = "git+https://gitlab.chromabits.com/etcinit/collective.git?rev=d976875136f684e04aa8e5a800d35d5a9c08e480#d976875136f684e04aa8e5a800d35d5a9c08e480"
 dependencies = [
  "clap",
  "figment",
+ "lazy_static",
  "log",
  "pretty_env_logger",
  "serde",
  "thiserror",
  "toml",
+ "xdg",
 ]
 
 [[package]]
 name = "concurrent-queue"
-version = "1.2.2"
+version = "1.2.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "30ed07550be01594c6026cff2a1d7fe9c8f683caa798e12b68694ac9e88286a3"
+checksum = "af4780a44ab5696ea9e28294517f1fffb421a83a25af521333c838635509db9c"
 dependencies = [
  "cache-padded",
 ]
 
 [[package]]
-name = "constant_time_eq"
-version = "0.1.5"
+name = "concurrent-queue"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bd7bef69dc86e3c610e4e7aed41035e2a7ed12e72dd7530f61327a6579a4390b"
+dependencies = [
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "console-api"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e57ff02e8ad8e06ab9731d5dc72dc23bef9200778eae1a89d555d8c42e5d4a86"
+dependencies = [
+ "prost",
+ "prost-types",
+ "tonic",
+ "tracing-core",
+]
+
+[[package]]
+name = "console-subscriber"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "22a3a81dfaf6b66bce5d159eddae701e3a002f194d378cbf7be5f053c281d9be"
+dependencies = [
+ "console-api",
+ "crossbeam-channel",
+ "crossbeam-utils",
+ "futures",
+ "hdrhistogram",
+ "humantime 2.1.0",
+ "prost-types",
+ "serde",
+ "serde_json",
+ "thread_local",
+ "tokio 1.21.2",
+ "tokio-stream",
+ "tonic",
+ "tracing",
+ "tracing-core",
+ "tracing-subscriber",
+]
+
+[[package]]
+name = "convert_case"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
+
+[[package]]
+name = "cookie"
+version = "0.16.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
+checksum = "344adc371239ef32293cb1c4fe519592fcf21206c79c02854320afcdf3ab4917"
+dependencies = [
+ "percent-encoding",
+ "time 0.3.17",
+ "version_check",
+]
 
 [[package]]
 name = "copyless"
@@ -789,9 +1025,9 @@ checksum = "a2df960f5d869b2dd8532793fde43eb5427cceb126c929747a26823ab0eeb536"
 
 [[package]]
 name = "core-foundation"
-version = "0.7.0"
+version = "0.9.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171"
+checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146"
 dependencies = [
  "core-foundation-sys",
  "libc",
@@ -799,74 +1035,132 @@ dependencies = [
 
 [[package]]
 name = "core-foundation-sys"
-version = "0.7.0"
+version = "0.8.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac"
+checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
 
 [[package]]
-name = "cpuid-bool"
-version = "0.1.2"
+name = "cpufeatures"
+version = "0.2.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634"
+checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320"
+dependencies = [
+ "libc",
+]
 
 [[package]]
 name = "crc32fast"
-version = "1.2.0"
+version = "1.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1"
+checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
 dependencies = [
- "cfg-if",
+ "cfg-if 1.0.0",
 ]
 
 [[package]]
 name = "crossbeam-channel"
-version = "0.4.3"
+version = "0.5.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09ee0cc8804d5393478d743b035099520087a5186f3b93fa58cec08fa62407b6"
+checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521"
 dependencies = [
- "cfg-if",
+ "cfg-if 1.0.0",
  "crossbeam-utils",
 ]
 
 [[package]]
 name = "crossbeam-utils"
-version = "0.7.2"
+version = "0.8.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
+checksum = "edbafec5fa1f196ca66527c1b12c2ec4745ca14b50f1ad8f9f6f720b55d11fac"
 dependencies = [
- "autocfg",
- "cfg-if",
- "lazy_static",
+ "cfg-if 1.0.0",
+]
+
+[[package]]
+name = "crypto-common"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
+dependencies = [
+ "generic-array",
+ "typenum",
 ]
 
 [[package]]
 name = "crypto-mac"
-version = "0.8.0"
+version = "0.11.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab"
+checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714"
 dependencies = [
- "generic-array 0.14.4",
+ "generic-array",
  "subtle",
 ]
 
 [[package]]
-name = "derive_more"
-version = "0.99.9"
+name = "ctor"
+version = "0.1.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096"
+dependencies = [
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "cxx"
+version = "1.0.81"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "97abf9f0eca9e52b7f81b945524e76710e6cb2366aead23b7d4fbf72e281f888"
+dependencies = [
+ "cc",
+ "cxxbridge-flags",
+ "cxxbridge-macro",
+ "link-cplusplus",
+]
+
+[[package]]
+name = "cxx-build"
+version = "1.0.81"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "298998b1cf6b5b2c8a7b023dfd45821825ce3ba8a8af55c921a0e734e4653f76"
+checksum = "7cc32cc5fea1d894b77d269ddb9f192110069a8a9c1f1d441195fba90553dea3"
 dependencies = [
+ "cc",
+ "codespan-reporting",
+ "once_cell",
  "proc-macro2",
  "quote",
+ "scratch",
  "syn",
 ]
 
 [[package]]
-name = "digest"
-version = "0.8.1"
+name = "cxxbridge-flags"
+version = "1.0.81"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ca220e4794c934dc6b1207c3b42856ad4c302f2df1712e9f8d2eec5afaacf1f"
+
+[[package]]
+name = "cxxbridge-macro"
+version = "1.0.81"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b846f081361125bfc8dc9d3940c84e1fd83ba54bbca7b17cd29483c828be0704"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "derive_more"
+version = "0.99.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
+checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321"
 dependencies = [
- "generic-array 0.12.3",
+ "convert_case",
+ "proc-macro2",
+ "quote",
+ "rustc_version",
+ "syn",
 ]
 
 [[package]]
@@ -875,24 +1169,43 @@ version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
 dependencies = [
- "generic-array 0.14.4",
+ "generic-array",
+]
+
+[[package]]
+name = "digest"
+version = "0.10.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "adfbc57365a37acbd2ebf2b64d7e69bb766e2fea813521ed536f5d0520dcf86c"
+dependencies = [
+ "block-buffer 0.10.3",
+ "crypto-common",
 ]
 
 [[package]]
 name = "dirs"
-version = "2.0.2"
+version = "4.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3"
+checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059"
 dependencies = [
- "cfg-if",
  "dirs-sys",
 ]
 
+[[package]]
+name = "dirs-next"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1"
+dependencies = [
+ "cfg-if 1.0.0",
+ "dirs-sys-next",
+]
+
 [[package]]
 name = "dirs-sys"
-version = "0.3.5"
+version = "0.3.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e93d7f5705de3e49895a2b5e0b8855a1c27f080192ae9c32a6432d50741a57a"
+checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
 dependencies = [
  "libc",
  "redox_users",
@@ -900,10 +1213,15 @@ dependencies = [
 ]
 
 [[package]]
-name = "discard"
-version = "1.0.4"
+name = "dirs-sys-next"
+version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0"
+checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d"
+dependencies = [
+ "libc",
+ "redox_users",
+ "winapi 0.3.9",
+]
 
 [[package]]
 name = "doc-comment"
@@ -913,30 +1231,30 @@ checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
 
 [[package]]
 name = "dtoa"
-version = "0.4.6"
+version = "0.4.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "134951f4028bdadb9b84baf4232681efbf277da25144b9b0ad65df75946c422b"
+checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0"
 
 [[package]]
 name = "either"
-version = "1.6.0"
+version = "1.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cd56b59865bce947ac5958779cfa508f6c3b9497cc762b7e24a12d11ccde2c4f"
+checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
 
 [[package]]
 name = "encoding_rs"
-version = "0.8.23"
+version = "0.8.31"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8ac63f94732332f44fe654443c46f6375d1939684c17b0afb6cb56b0456e171"
+checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b"
 dependencies = [
- "cfg-if",
+ "cfg-if 1.0.0",
 ]
 
 [[package]]
 name = "enum-as-inner"
-version = "0.3.3"
+version = "0.3.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7c5f0096a91d210159eceb2ff5e1c4da18388a170e1e3ce948aac9c8fdbbf595"
+checksum = "570d109b813e904becc80d8d5da38376818a143348413f7149f1340fe04754d4"
 dependencies = [
  "heck",
  "proc-macro2",
@@ -951,7 +1269,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
 dependencies = [
  "atty",
- "humantime",
+ "humantime 1.3.0",
  "log",
  "regex",
  "termcolor",
@@ -962,19 +1280,22 @@ name = "espresso"
 version = "1.0.1"
 dependencies = [
  "actix",
- "actix-http",
- "actix-rt",
- "actix-service",
+ "actix-files",
+ "actix-http 1.0.1",
+ "actix-rt 2.7.0",
+ "actix-service 2.0.2",
  "actix-web",
  "anyhow",
  "async-compat",
  "async-compression",
+ "async-recursion",
  "async-tar",
  "async-trait",
  "bitflags",
- "bytes",
+ "bytes 1.2.1",
  "clap",
  "collective",
+ "console-subscriber",
  "futures-core",
  "futures-util",
  "handlebars",
@@ -993,18 +1314,19 @@ dependencies = [
  "serde_derive",
  "serde_json",
  "snafu",
- "tokio",
+ "tokio 1.21.2",
+ "tokio-stream",
  "tokio-tar",
- "tokio-util 0.3.1",
+ "tokio-util 0.7.4",
  "toml",
  "url",
 ]
 
 [[package]]
 name = "event-listener"
-version = "2.4.0"
+version = "2.5.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e1cd41440ae7e4734bbd42302f63eaba892afc93a3912dad84006247f0dedb0e"
+checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
 
 [[package]]
 name = "failure"
@@ -1028,26 +1350,26 @@ dependencies = [
  "synstructure",
 ]
 
-[[package]]
-name = "fake-simd"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
-
 [[package]]
 name = "fastrand"
-version = "1.3.5"
+version = "1.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c85295147490b8fcf2ea3d104080a105a8b2c63f9c319e82c02d8e952388919"
+checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499"
+dependencies = [
+ "instant",
+]
 
 [[package]]
 name = "figment"
-version = "0.10.0"
+version = "0.10.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f273b2f81f067bb5553f562feb98794d6c704f049d333f920d69211965a30448"
+checksum = "4e56602b469b2201400dec66a66aec5a9b8761ee97cd1b8c96ab2483fcc16cc9"
 dependencies = [
+ "atomic",
  "pear",
  "serde",
+ "serde_json",
+ "serde_yaml",
  "toml",
  "uncased",
  "version_check",
@@ -1055,25 +1377,23 @@ dependencies = [
 
 [[package]]
 name = "filetime"
-version = "0.2.12"
+version = "0.2.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3ed85775dcc68644b5c950ac06a2b23768d3bc9390464151aaf27136998dcf9e"
+checksum = "4b9663d381d07ae25dc88dbdf27df458faa83a9b25336bcac83d5e452b5fc9d3"
 dependencies = [
- "cfg-if",
+ "cfg-if 1.0.0",
  "libc",
  "redox_syscall",
- "winapi 0.3.9",
+ "windows-sys 0.42.0",
 ]
 
 [[package]]
 name = "flate2"
-version = "1.0.16"
+version = "1.0.24"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "68c90b0fc46cf89d227cc78b40e494ff81287a92dd07631e5af0d06fe3cf885e"
+checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6"
 dependencies = [
- "cfg-if",
  "crc32fast",
- "libc",
  "miniz_oxide",
 ]
 
@@ -1098,6 +1418,15 @@ version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
 
+[[package]]
+name = "form_urlencoded"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8"
+dependencies = [
+ "percent-encoding",
+]
+
 [[package]]
 name = "fuchsia-zircon"
 version = "0.3.3"
@@ -1116,9 +1445,9 @@ checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
 
 [[package]]
 name = "futures"
-version = "0.3.5"
+version = "0.3.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e05b85ec287aac0dc34db7d4a569323df697f9c55b99b15d6b4ef8cde49f613"
+checksum = "38390104763dc37a5145a53c29c63c1290b5d316d6086ec32c293f6736051bb0"
 dependencies = [
  "futures-channel",
  "futures-core",
@@ -1131,9 +1460,9 @@ dependencies = [
 
 [[package]]
 name = "futures-channel"
-version = "0.3.5"
+version = "0.3.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f366ad74c28cca6ba456d95e6422883cfb4b252a83bed929c83abfdbbf2967d5"
+checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed"
 dependencies = [
  "futures-core",
  "futures-sink",
@@ -1141,15 +1470,15 @@ dependencies = [
 
 [[package]]
 name = "futures-core"
-version = "0.3.5"
+version = "0.3.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "59f5fff90fd5d971f936ad674802482ba441b6f09ba5e15fd8b39145582ca399"
+checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac"
 
 [[package]]
 name = "futures-executor"
-version = "0.3.5"
+version = "0.3.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "10d6bb888be1153d3abeb9006b11b02cf5e9b209fda28693c31ae1e4e012e314"
+checksum = "7acc85df6714c176ab5edf386123fafe217be88c0840ec11f199441134a074e2"
 dependencies = [
  "futures-core",
  "futures-task",
@@ -1158,32 +1487,31 @@ dependencies = [
 
 [[package]]
 name = "futures-io"
-version = "0.3.5"
+version = "0.3.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "de27142b013a8e869c14957e6d2edeef89e97c289e69d042ee3a49acd8b51789"
+checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb"
 
 [[package]]
 name = "futures-lite"
-version = "0.1.11"
+version = "1.12.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "97999970129b808f0ccba93211201d431fcc12d7e1ffae03a61b5cedd1a7ced2"
+checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48"
 dependencies = [
  "fastrand",
  "futures-core",
  "futures-io",
  "memchr",
- "parking 2.0.0",
- "pin-project-lite 0.1.7",
+ "parking",
+ "pin-project-lite 0.2.9",
  "waker-fn",
 ]
 
 [[package]]
 name = "futures-macro"
-version = "0.3.5"
+version = "0.3.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d0b5a30a4328ab5473878237c447333c093297bded83a4983d10f4deea240d39"
+checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d"
 dependencies = [
- "proc-macro-hack",
  "proc-macro2",
  "quote",
  "syn",
@@ -1191,34 +1519,21 @@ dependencies = [
 
 [[package]]
 name = "futures-sink"
-version = "0.3.5"
+version = "0.3.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f2032893cb734c7a05d85ce0cc8b8c4075278e93b24b66f9de99d6eb0fa8acc"
+checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9"
 
 [[package]]
 name = "futures-task"
-version = "0.3.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bdb66b5f09e22019b1ab0830f7785bcea8e7a42148683f99214f73f8ec21a626"
-dependencies = [
- "once_cell",
-]
-
-[[package]]
-name = "futures-timer"
-version = "3.0.2"
+version = "0.3.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c"
-dependencies = [
- "gloo-timers",
- "send_wrapper",
-]
+checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea"
 
 [[package]]
 name = "futures-util"
-version = "0.3.5"
+version = "0.3.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8764574ff08b701a084482c3c7031349104b07ac897393010494beaa18ce32c6"
+checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6"
 dependencies = [
  "futures-channel",
  "futures-core",
@@ -1227,10 +1542,8 @@ dependencies = [
  "futures-sink",
  "futures-task",
  "memchr",
- "pin-project",
+ "pin-project-lite 0.2.9",
  "pin-utils",
- "proc-macro-hack",
- "proc-macro-nested",
  "slab",
 ]
 
@@ -1245,60 +1558,61 @@ dependencies = [
 
 [[package]]
 name = "generic-array"
-version = "0.12.3"
+version = "0.14.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
+checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9"
 dependencies = [
  "typenum",
+ "version_check",
 ]
 
 [[package]]
-name = "generic-array"
-version = "0.14.4"
+name = "getrandom"
+version = "0.1.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817"
+checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
 dependencies = [
- "typenum",
- "version_check",
+ "cfg-if 1.0.0",
+ "libc",
+ "wasi 0.9.0+wasi-snapshot-preview1",
 ]
 
 [[package]]
 name = "getrandom"
-version = "0.1.14"
+version = "0.2.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
+checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
 dependencies = [
- "cfg-if",
+ "cfg-if 1.0.0",
  "libc",
- "wasi",
+ "wasi 0.11.0+wasi-snapshot-preview1",
 ]
 
 [[package]]
 name = "gimli"
-version = "0.22.0"
+version = "0.26.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aaf91faf136cb47367fa430cd46e37a788775e7fa104f8b4bcb3861dc389b724"
+checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d"
 
 [[package]]
 name = "gloo-timers"
-version = "0.2.1"
+version = "0.2.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "47204a46aaff920a1ea58b11d03dec6f704287d27561724a4631e450654a891f"
+checksum = "5fb7d06c1c8cc2a29bee7ec961009a0b2caa0793ee4900c2ffb348734ba1c8f9"
 dependencies = [
  "futures-channel",
  "futures-core",
  "js-sys",
  "wasm-bindgen",
- "web-sys",
 ]
 
 [[package]]
 name = "h2"
-version = "0.2.6"
+version = "0.2.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "993f9e0baeed60001cf565546b0d3dbe6a6ad23f2bd31644a133c641eccf6d53"
+checksum = "5e4728fd124914ad25e99e3d15a9361a879f6620f63cb56bbb08f95abb97a535"
 dependencies = [
- "bytes",
+ "bytes 0.5.6",
  "fnv",
  "futures-core",
  "futures-sink",
@@ -1306,63 +1620,90 @@ dependencies = [
  "http",
  "indexmap",
  "slab",
- "tokio",
+ "tokio 0.2.25",
  "tokio-util 0.3.1",
  "tracing",
+ "tracing-futures",
+]
+
+[[package]]
+name = "h2"
+version = "0.3.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4"
+dependencies = [
+ "bytes 1.2.1",
+ "fnv",
+ "futures-core",
+ "futures-sink",
+ "futures-util",
+ "http",
+ "indexmap",
+ "slab",
+ "tokio 1.21.2",
+ "tokio-util 0.7.4",
+ "tracing",
 ]
 
 [[package]]
 name = "handlebars"
-version = "3.4.0"
+version = "3.5.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5deefd4816fb852b1ff3cb48f6c41da67be2d0e1d20b26a7a3b076da11f064b1"
+checksum = "4498fc115fa7d34de968184e473529abb40eeb6be8bc5f7faba3d08c316cb3e3"
 dependencies = [
  "log",
  "pest",
  "pest_derive",
- "quick-error 2.0.0",
+ "quick-error 2.0.1",
  "serde",
  "serde_json",
 ]
 
 [[package]]
 name = "hashbrown"
-version = "0.8.2"
+version = "0.12.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e91b62f79061a0bc2e046024cb7ba44b08419ed238ecbd9adbd787434b9e8c25"
+checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
+
+[[package]]
+name = "hdrhistogram"
+version = "7.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f19b9f54f7c7f55e31401bb647626ce0cf0f67b0004982ce815b3ee72a02aa8"
 dependencies = [
- "autocfg",
+ "base64 0.13.1",
+ "byteorder",
+ "flate2",
+ "nom",
+ "num-traits",
 ]
 
 [[package]]
 name = "heck"
-version = "0.3.1"
+version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
-dependencies = [
- "unicode-segmentation",
-]
+checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
 
 [[package]]
 name = "hermit-abi"
-version = "0.1.15"
+version = "0.1.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3deed196b6e7f9e44a2ae8d94225d80302d81208b1bb673fd21fe634645c85a9"
+checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
 dependencies = [
  "libc",
 ]
 
 [[package]]
 name = "hex"
-version = "0.4.2"
+version = "0.4.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35"
+checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
 
 [[package]]
 name = "hmac"
-version = "0.8.1"
+version = "0.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840"
+checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b"
 dependencies = [
  "crypto-mac",
  "digest 0.9.0",
@@ -1381,93 +1722,164 @@ dependencies = [
 
 [[package]]
 name = "http"
-version = "0.2.1"
+version = "0.2.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "28d569972648b2c512421b5f2a405ad6ac9666547189d0c5477a3f200f3e02f9"
+checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399"
 dependencies = [
- "bytes",
+ "bytes 1.2.1",
  "fnv",
- "itoa",
+ "itoa 1.0.4",
 ]
 
 [[package]]
 name = "http-body"
-version = "0.3.1"
+version = "0.4.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "13d5ff830006f7646652e057693569bfe0d51760c0085a071769d142a205111b"
+checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
 dependencies = [
- "bytes",
+ "bytes 1.2.1",
  "http",
+ "pin-project-lite 0.2.9",
 ]
 
 [[package]]
-name = "httparse"
-version = "1.3.4"
+name = "http-range"
+version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9"
+checksum = "21dec9db110f5f872ed9699c3ecf50cf16f423502706ba5c72462e28d3157573"
 
 [[package]]
-name = "humantime"
-version = "1.3.0"
+name = "http-range-header"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0bfe8eed0a9285ef776bb792479ea3834e8b94e13d615c2f66d03dd50a435a29"
+
+[[package]]
+name = "httparse"
+version = "1.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
+
+[[package]]
+name = "httpdate"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
+
+[[package]]
+name = "humantime"
+version = "1.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
 dependencies = [
  "quick-error 1.2.3",
 ]
 
+[[package]]
+name = "humantime"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
+
 [[package]]
 name = "hyper"
-version = "0.13.7"
+version = "0.14.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3e68a8dd9716185d9e64ea473ea6ef63529252e3e27623295a0378a19665d5eb"
+checksum = "034711faac9d2166cb1baf1a2fb0b60b1f277f8492fd72176c17f3515e1abd3c"
 dependencies = [
- "bytes",
+ "bytes 1.2.1",
  "futures-channel",
  "futures-core",
  "futures-util",
- "h2",
+ "h2 0.3.15",
  "http",
  "http-body",
  "httparse",
- "itoa",
- "pin-project",
- "socket2",
- "time 0.1.43",
- "tokio",
+ "httpdate",
+ "itoa 1.0.4",
+ "pin-project-lite 0.2.9",
+ "socket2 0.4.7",
+ "tokio 1.21.2",
  "tower-service",
  "tracing",
  "want",
 ]
 
+[[package]]
+name = "hyper-timeout"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1"
+dependencies = [
+ "hyper",
+ "pin-project-lite 0.2.9",
+ "tokio 1.21.2",
+ "tokio-io-timeout",
+]
+
 [[package]]
 name = "hyper-tls"
-version = "0.4.3"
+version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d979acc56dcb5b8dddba3917601745e877576475aa046df3226eabdecef78eed"
+checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
 dependencies = [
- "bytes",
+ "bytes 1.2.1",
  "hyper",
  "native-tls",
- "tokio",
- "tokio-tls",
+ "tokio 1.21.2",
+ "tokio-native-tls",
+]
+
+[[package]]
+name = "iana-time-zone"
+version = "0.1.53"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765"
+dependencies = [
+ "android_system_properties",
+ "core-foundation-sys",
+ "iana-time-zone-haiku",
+ "js-sys",
+ "wasm-bindgen",
+ "winapi 0.3.9",
+]
+
+[[package]]
+name = "iana-time-zone-haiku"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca"
+dependencies = [
+ "cxx",
+ "cxx-build",
 ]
 
 [[package]]
 name = "idna"
-version = "0.2.0"
+version = "0.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9"
+checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8"
 dependencies = [
  "matches",
  "unicode-bidi",
  "unicode-normalization",
 ]
 
+[[package]]
+name = "idna"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6"
+dependencies = [
+ "unicode-bidi",
+ "unicode-normalization",
+]
+
 [[package]]
 name = "indexmap"
-version = "1.5.1"
+version = "1.9.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "86b45e59b16c76b11bf9738fd5d38879d3bd28ad292d7b313608becb17ae2df9"
+checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e"
 dependencies = [
  "autocfg",
  "hashbrown",
@@ -1475,24 +1887,24 @@ dependencies = [
 
 [[package]]
 name = "indoc"
-version = "1.0.2"
+version = "1.0.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "644defcefee68d7805653a682e99a2e2a5014a1fc3cc9be7059a215844eeea6f"
-dependencies = [
- "unindent",
-]
+checksum = "adab1eaa3408fb7f0c777a73e7465fd5656136fc93b670eb6df3c88c2c1344e3"
 
 [[package]]
 name = "inlinable_string"
-version = "0.1.14"
+version = "0.1.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3094308123a0e9fd59659ce45e22de9f53fc1d2ac6e1feb9fef988e4f76cad77"
+checksum = "c8fae54786f62fb2918dcfae3d568594e50eb9b5c25bf04371af6fe7516452fb"
 
 [[package]]
 name = "instant"
-version = "0.1.6"
+version = "0.1.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5b141fdc7836c525d4d594027d318c84161ca17aaf8113ab1f81ab93ae897485"
+checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
+dependencies = [
+ "cfg-if 1.0.0",
+]
 
 [[package]]
 name = "iovec"
@@ -1509,23 +1921,47 @@ version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f7e2f18aece9709094573a9f24f483c4f65caa4298e2f7ae1b71cc65d853fad7"
 dependencies = [
- "socket2",
+ "socket2 0.3.19",
  "widestring",
  "winapi 0.3.9",
  "winreg",
 ]
 
+[[package]]
+name = "itertools"
+version = "0.10.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
+dependencies = [
+ "either",
+]
+
+[[package]]
+name = "itoa"
+version = "0.4.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
+
 [[package]]
 name = "itoa"
-version = "0.4.6"
+version = "1.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6"
+checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc"
+
+[[package]]
+name = "jobserver"
+version = "0.1.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "068b1ee6743e4d11fb9c6a1e6064b3693a1b600e7f5f5988047d98b3dc9fb90b"
+dependencies = [
+ "libc",
+]
 
 [[package]]
 name = "js-sys"
-version = "0.3.44"
+version = "0.3.60"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "85a7e2c92a4804dd459b86c339278d0fe87cf93757fae222c3fa3ae75458bc73"
+checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47"
 dependencies = [
  "wasm-bindgen",
 ]
@@ -1555,6 +1991,12 @@ version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a"
 
+[[package]]
+name = "language-tags"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388"
+
 [[package]]
 name = "lazy_static"
 version = "1.4.0"
@@ -1563,41 +2005,61 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
 
 [[package]]
 name = "libc"
-version = "0.2.74"
+version = "0.2.137"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89"
+
+[[package]]
+name = "link-cplusplus"
+version = "1.0.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a2f02823cf78b754822df5f7f268fb59822e7296276d3e069d8e8cb26a14bd10"
+checksum = "9272ab7b96c9046fbc5bc56c06c117cb639fe2d509df0c421cad82d2915cf369"
+dependencies = [
+ "cc",
+]
 
 [[package]]
 name = "linked-hash-map"
-version = "0.5.3"
+version = "0.5.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8dd5a6d5999d9907cda8ed67bbd137d3af8085216c2ac62de5be860bd41f304a"
+checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
 
 [[package]]
-name = "lock_api"
-version = "0.3.4"
+name = "local-channel"
+version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75"
+checksum = "7f303ec0e94c6c54447f84f3b0ef7af769858a9c4ef56ef2a986d3dcd4c3fc9c"
 dependencies = [
- "scopeguard",
+ "futures-core",
+ "futures-sink",
+ "futures-util",
+ "local-waker",
 ]
 
+[[package]]
+name = "local-waker"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e34f76eb3611940e0e7d53a9aaa4e6a3151f69541a282fd0dad5571420c53ff1"
+
 [[package]]
 name = "lock_api"
-version = "0.4.1"
+version = "0.4.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "28247cc5a5be2f05fbcd76dd0cf2c7d3b5400cb978a28042abcd4fa0b3f8261c"
+checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df"
 dependencies = [
+ "autocfg",
  "scopeguard",
 ]
 
 [[package]]
 name = "log"
-version = "0.4.11"
+version = "0.4.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
+checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
 dependencies = [
- "cfg-if",
+ "cfg-if 1.0.0",
+ "value-bag",
 ]
 
 [[package]]
@@ -1610,34 +2072,48 @@ dependencies = [
 ]
 
 [[package]]
-name = "maplit"
-version = "1.0.2"
+name = "match_cfg"
+version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
+checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4"
 
 [[package]]
-name = "match_cfg"
+name = "matchers"
 version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4"
+checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"
+dependencies = [
+ "regex-automata",
+]
 
 [[package]]
 name = "matches"
-version = "0.1.8"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
+
+[[package]]
+name = "matchit"
+version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
+checksum = "73cbba799671b762df5a175adf59ce145165747bb891505c43d09aefbbf38beb"
 
 [[package]]
-name = "md5"
-version = "0.7.0"
+name = "md-5"
+version = "0.9.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771"
+checksum = "7b5a279bb9607f9f53c22d496eade00d138d1bdcccd07d74650387cf94942a15"
+dependencies = [
+ "block-buffer 0.9.0",
+ "digest 0.9.0",
+ "opaque-debug",
+]
 
 [[package]]
 name = "memchr"
-version = "2.3.3"
+version = "2.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
+checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
 
 [[package]]
 name = "mime"
@@ -1647,52 +2123,58 @@ checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
 
 [[package]]
 name = "mime_guess"
-version = "2.0.3"
+version = "2.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2684d4c2e97d99848d30b324b00c8fcc7e5c897b7cbb5819b09e7c90e8baf212"
+checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef"
 dependencies = [
  "mime",
  "unicase",
 ]
 
+[[package]]
+name = "minimal-lexical"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
+
 [[package]]
 name = "miniz_oxide"
-version = "0.4.0"
+version = "0.5.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be0f75932c1f6cfae3c04000e40114adf955636e19040f9c0a2c380702aa1c7f"
+checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34"
 dependencies = [
  "adler",
 ]
 
 [[package]]
 name = "mio"
-version = "0.6.22"
+version = "0.6.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fce347092656428bc8eaf6201042cb551b8d67855af7374542a92a0fbfcac430"
+checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4"
 dependencies = [
- "cfg-if",
+ "cfg-if 0.1.10",
  "fuchsia-zircon",
  "fuchsia-zircon-sys",
  "iovec",
  "kernel32-sys",
  "libc",
  "log",
- "miow 0.2.1",
+ "miow",
  "net2",
  "slab",
  "winapi 0.2.8",
 ]
 
 [[package]]
-name = "mio-named-pipes"
-version = "0.1.7"
+name = "mio"
+version = "0.8.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0840c1c50fd55e521b247f949c241c9997709f23bd7f023b9762cd561e935656"
+checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de"
 dependencies = [
+ "libc",
  "log",
- "mio",
- "miow 0.3.5",
- "winapi 0.3.9",
+ "wasi 0.11.0+wasi-snapshot-preview1",
+ "windows-sys 0.42.0",
 ]
 
 [[package]]
@@ -1703,14 +2185,14 @@ checksum = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0"
 dependencies = [
  "iovec",
  "libc",
- "mio",
+ "mio 0.6.23",
 ]
 
 [[package]]
 name = "miow"
-version = "0.2.1"
+version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
+checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d"
 dependencies = [
  "kernel32-sys",
  "net2",
@@ -1718,32 +2200,11 @@ dependencies = [
  "ws2_32-sys",
 ]
 
-[[package]]
-name = "miow"
-version = "0.3.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "07b88fb9795d4d36d62a012dfbf49a8f5cf12751f36d31a9dbe66d528e58979e"
-dependencies = [
- "socket2",
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "multitask"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c09c35271e7dcdb5f709779111f2c8e8ab8e06c1b587c1c6a9e179d865aaa5b4"
-dependencies = [
- "async-task",
- "concurrent-queue",
- "fastrand",
-]
-
 [[package]]
 name = "native-tls"
-version = "0.2.4"
+version = "0.2.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2b0d88c06fe90d5ee94048ba40409ef1d9315d86f6f38c2efdaad4fb50c58b2d"
+checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e"
 dependencies = [
  "lazy_static",
  "libc",
@@ -1759,20 +2220,30 @@ dependencies = [
 
 [[package]]
 name = "net2"
-version = "0.2.34"
+version = "0.2.38"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2ba7c918ac76704fb42afcbbb43891e72731f3dcca3bef2a19786297baf14af7"
+checksum = "74d0df99cfcd2530b2e694f6e17e7f37b8e26bb23983ac530c0c97408837c631"
 dependencies = [
- "cfg-if",
+ "cfg-if 0.1.10",
  "libc",
  "winapi 0.3.9",
 ]
 
+[[package]]
+name = "nom"
+version = "7.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36"
+dependencies = [
+ "memchr",
+ "minimal-lexical",
+]
+
 [[package]]
 name = "num-integer"
-version = "0.1.43"
+version = "0.1.45"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b"
+checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
 dependencies = [
  "autocfg",
  "num-traits",
@@ -1780,18 +2251,18 @@ dependencies = [
 
 [[package]]
 name = "num-traits"
-version = "0.2.12"
+version = "0.2.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611"
+checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
 dependencies = [
  "autocfg",
 ]
 
 [[package]]
 name = "num_cpus"
-version = "1.13.0"
+version = "1.14.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
+checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5"
 dependencies = [
  "hermit-abi",
  "libc",
@@ -1799,21 +2270,18 @@ dependencies = [
 
 [[package]]
 name = "object"
-version = "0.20.0"
+version = "0.29.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ab52be62400ca80aa00285d25253d7f7c437b7375c4de678f5405d3afe82ca5"
+checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53"
+dependencies = [
+ "memchr",
+]
 
 [[package]]
 name = "once_cell"
-version = "1.4.1"
+version = "1.16.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "260e51e7efe62b592207e9e13a68e43692a7a279171d6ba57abd208bf23645ad"
-
-[[package]]
-name = "opaque-debug"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
+checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860"
 
 [[package]]
 name = "opaque-debug"
@@ -1823,29 +2291,41 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
 
 [[package]]
 name = "openssl"
-version = "0.10.30"
+version = "0.10.42"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8d575eff3665419f9b83678ff2815858ad9d11567e082f5ac1814baba4e2bcb4"
+checksum = "12fc0523e3bd51a692c8850d075d74dc062ccf251c0110668cbd921917118a13"
 dependencies = [
  "bitflags",
- "cfg-if",
+ "cfg-if 1.0.0",
  "foreign-types",
- "lazy_static",
  "libc",
+ "once_cell",
+ "openssl-macros",
  "openssl-sys",
 ]
 
+[[package]]
+name = "openssl-macros"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
 [[package]]
 name = "openssl-probe"
-version = "0.1.2"
+version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
+checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
 
 [[package]]
 name = "openssl-sys"
-version = "0.9.58"
+version = "0.9.77"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a842db4709b604f0fe5d1170ae3565899be2ad3d9cbc72dedc789ac0511f78de"
+checksum = "b03b84c3b2d099b81f0953422b4d4ad58761589d0229b5506356afca05a3670a"
 dependencies = [
  "autocfg",
  "cc",
@@ -1856,15 +2336,9 @@ dependencies = [
 
 [[package]]
 name = "os_str_bytes"
-version = "2.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "afb2e1c3ee07430c2cf76151675e583e0f19985fa6efae47d6848a3e2c824f85"
-
-[[package]]
-name = "parking"
-version = "1.0.6"
+version = "6.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6cb300f271742d4a2a66c01b6b2fa0c83dfebd2e0bf11addb879a3547b4ed87c"
+checksum = "7b5bf27447411e9ee3ff51186bf7a08e16c341efdde93f4d823e8844429bed7e"
 
 [[package]]
 name = "parking"
@@ -1874,33 +2348,33 @@ checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72"
 
 [[package]]
 name = "parking_lot"
-version = "0.10.2"
+version = "0.11.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e"
+checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
 dependencies = [
- "lock_api 0.3.4",
- "parking_lot_core 0.7.2",
+ "instant",
+ "lock_api",
+ "parking_lot_core 0.8.5",
 ]
 
 [[package]]
 name = "parking_lot"
-version = "0.11.0"
+version = "0.12.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a4893845fa2ca272e647da5d0e46660a314ead9c2fdd9a883aabc32e481a8733"
+checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
 dependencies = [
- "instant",
- "lock_api 0.4.1",
- "parking_lot_core 0.8.0",
+ "lock_api",
+ "parking_lot_core 0.9.4",
 ]
 
 [[package]]
 name = "parking_lot_core"
-version = "0.7.2"
+version = "0.8.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3"
+checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216"
 dependencies = [
- "cfg-if",
- "cloudabi 0.0.3",
+ "cfg-if 1.0.0",
+ "instant",
  "libc",
  "redox_syscall",
  "smallvec",
@@ -1909,24 +2383,28 @@ dependencies = [
 
 [[package]]
 name = "parking_lot_core"
-version = "0.8.0"
+version = "0.9.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c361aa727dd08437f2f1447be8b59a33b0edd15e0fcee698f935613d9efbca9b"
+checksum = "4dc9e0dc2adc1c69d09143aff38d3d30c5c3f0df0dad82e6d25547af174ebec0"
 dependencies = [
- "cfg-if",
- "cloudabi 0.1.0",
- "instant",
+ "cfg-if 1.0.0",
  "libc",
  "redox_syscall",
  "smallvec",
- "winapi 0.3.9",
+ "windows-sys 0.42.0",
 ]
 
+[[package]]
+name = "paste"
+version = "1.0.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1de2e551fb905ac83f73f7aedf2f0cb4a0da7e35efa24a202a936269f1f18e1"
+
 [[package]]
 name = "pear"
-version = "0.2.0"
+version = "0.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09f612cbd0f9dd03f5dd28a191c48e4148c3b027e41207b32eee130373c6c941"
+checksum = "15e44241c5e4c868e3eaa78b7c1848cadd6344ed4f54d029832d32b415a58702"
 dependencies = [
  "inlinable_string",
  "pear_codegen",
@@ -1935,9 +2413,9 @@ dependencies = [
 
 [[package]]
 name = "pear_codegen"
-version = "0.2.0"
+version = "0.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "602cf1780ee9bbca663ea75769e05643e16fe87d7c8ac9f4f385a2ed8940a75c"
+checksum = "82a5ca643c2303ecb740d506539deba189e16f2754040a42901cd8105d0282d0"
 dependencies = [
  "proc-macro2",
  "proc-macro2-diagnostics",
@@ -1947,24 +2425,25 @@ dependencies = [
 
 [[package]]
 name = "percent-encoding"
-version = "2.1.0"
+version = "2.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
+checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
 
 [[package]]
 name = "pest"
-version = "2.1.3"
+version = "2.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53"
+checksum = "a528564cc62c19a7acac4d81e01f39e53e25e17b934878f4c6d25cc2836e62f8"
 dependencies = [
+ "thiserror",
  "ucd-trie",
 ]
 
 [[package]]
 name = "pest_derive"
-version = "2.1.0"
+version = "2.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0"
+checksum = "d5fd9bc6500181952d34bd0b2b0163a54d794227b498be0b7afa7698d0a7b18f"
 dependencies = [
  "pest",
  "pest_generator",
@@ -1972,9 +2451,9 @@ dependencies = [
 
 [[package]]
 name = "pest_generator"
-version = "2.1.3"
+version = "2.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55"
+checksum = "d2610d5ac5156217b4ff8e46ddcef7cdf44b273da2ac5bca2ecbfa86a330e7c4"
 dependencies = [
  "pest",
  "pest_meta",
@@ -1985,29 +2464,49 @@ dependencies = [
 
 [[package]]
 name = "pest_meta"
-version = "2.1.3"
+version = "2.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d"
+checksum = "824749bf7e21dd66b36fbe26b3f45c713879cccd4a009a917ab8e045ca8246fe"
 dependencies = [
- "maplit",
+ "once_cell",
  "pest",
- "sha-1",
+ "sha1 0.10.5",
+]
+
+[[package]]
+name = "pin-project"
+version = "0.4.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3ef0f924a5ee7ea9cbcea77529dba45f8a9ba9f622419fe3386ca581a3ae9d5a"
+dependencies = [
+ "pin-project-internal 0.4.30",
 ]
 
 [[package]]
 name = "pin-project"
-version = "0.4.23"
+version = "1.0.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca4433fff2ae79342e497d9f8ee990d174071408f28f726d6d83af93e58e48aa"
+checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc"
 dependencies = [
- "pin-project-internal",
+ "pin-project-internal 1.0.12",
 ]
 
 [[package]]
 name = "pin-project-internal"
-version = "0.4.23"
+version = "0.4.30"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2c0e815c3ee9a031fdf5af21c10aa17c573c9c6a566328d99e3936c34e36461f"
+checksum = "851c8d0ce9bebe43790dedfc86614c23494ac9f423dd618d3a61fc693eafe61e"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "pin-project-internal"
+version = "1.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -2016,15 +2515,15 @@ dependencies = [
 
 [[package]]
 name = "pin-project-lite"
-version = "0.1.7"
+version = "0.1.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "282adbf10f2698a7a77f8e983a74b2d18176c19a7fd32a45446139ae7b02b715"
+checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777"
 
 [[package]]
 name = "pin-project-lite"
-version = "0.2.0"
+version = "0.2.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6b063f57ec186e6140e2b8b6921e5f1bd89c7356dda5b33acc5401203ca6131c"
+checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
 
 [[package]]
 name = "pin-utils"
@@ -2034,28 +2533,29 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
 
 [[package]]
 name = "pkg-config"
-version = "0.3.18"
+version = "0.3.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d36492546b6af1463394d46f0c834346f31548646f6ba10849802c9c9a27ac33"
+checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160"
 
 [[package]]
 name = "polling"
-version = "0.1.9"
+version = "2.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8fffa183f6bd5f1a8a3e1f60ce2f8d5621e350eed84a62d6daaa5b9d1aaf6fbd"
+checksum = "ab4609a838d88b73d8238967b60dd115cc08d38e2bbaf51ee1e4b695f89122e2"
 dependencies = [
- "cfg-if",
+ "autocfg",
+ "cfg-if 1.0.0",
  "libc",
  "log",
- "wepoll-sys-stjepang",
+ "wepoll-ffi",
  "winapi 0.3.9",
 ]
 
 [[package]]
 name = "ppv-lite86"
-version = "0.2.8"
+version = "0.2.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea"
+checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
 
 [[package]]
 name = "pretty_env_logger"
@@ -2091,25 +2591,13 @@ dependencies = [
  "version_check",
 ]
 
-[[package]]
-name = "proc-macro-hack"
-version = "0.5.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "99c605b9a0adc77b7211c6b1f722dcb613d68d66859a44f3d485a6da332b0598"
-
-[[package]]
-name = "proc-macro-nested"
-version = "0.1.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eba180dafb9038b050a4c280019bbedf9f2467b61e5d892dcad585bb57aadc5a"
-
 [[package]]
 name = "proc-macro2"
-version = "1.0.19"
+version = "1.0.47"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "04f5f085b5d71e2188cb8271e5da0161ad52c3f227a661a3c135fdf28e258b12"
+checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725"
 dependencies = [
- "unicode-xid",
+ "unicode-ident",
 ]
 
 [[package]]
@@ -2125,6 +2613,39 @@ dependencies = [
  "yansi",
 ]
 
+[[package]]
+name = "prost"
+version = "0.11.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a0841812012b2d4a6145fae9a6af1534873c32aa67fff26bd09f8fa42c83f95a"
+dependencies = [
+ "bytes 1.2.1",
+ "prost-derive",
+]
+
+[[package]]
+name = "prost-derive"
+version = "0.11.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "164ae68b6587001ca506d3bf7f1000bfa248d0e1217b618108fba4ec1d0cc306"
+dependencies = [
+ "anyhow",
+ "itertools",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "prost-types"
+version = "0.11.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "747761bc3dc48f9a34553bf65605cf6cb6288ba219f3450b4275dbd81539551a"
+dependencies = [
+ "bytes 1.2.1",
+ "prost",
+]
+
 [[package]]
 name = "quick-error"
 version = "1.2.3"
@@ -2133,15 +2654,15 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
 
 [[package]]
 name = "quick-error"
-version = "2.0.0"
+version = "2.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3ac73b1112776fc109b2e61909bc46c7e1bf0d7f690ffb1676553acce16d5cda"
+checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3"
 
 [[package]]
 name = "quote"
-version = "1.0.7"
+version = "1.0.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
+checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
 dependencies = [
  "proc-macro2",
 ]
@@ -2152,21 +2673,42 @@ version = "0.7.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
 dependencies = [
- "getrandom",
+ "getrandom 0.1.16",
  "libc",
- "rand_chacha",
- "rand_core",
+ "rand_chacha 0.2.2",
+ "rand_core 0.5.1",
  "rand_hc",
 ]
 
 [[package]]
-name = "rand_chacha"
-version = "0.2.2"
+name = "rand"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
+dependencies = [
+ "libc",
+ "rand_chacha 0.3.1",
+ "rand_core 0.6.4",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
 dependencies = [
  "ppv-lite86",
- "rand_core",
+ "rand_core 0.5.1",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
+dependencies = [
+ "ppv-lite86",
+ "rand_core 0.6.4",
 ]
 
 [[package]]
@@ -2175,7 +2717,16 @@ version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
 dependencies = [
- "getrandom",
+ "getrandom 0.1.16",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
+dependencies = [
+ "getrandom 0.2.8",
 ]
 
 [[package]]
@@ -2184,43 +2735,54 @@ version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
 dependencies = [
- "rand_core",
+ "rand_core 0.5.1",
 ]
 
 [[package]]
 name = "redox_syscall"
-version = "0.1.57"
+version = "0.2.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
+checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
+dependencies = [
+ "bitflags",
+]
 
 [[package]]
 name = "redox_users"
-version = "0.3.5"
+version = "0.4.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d"
+checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
 dependencies = [
- "getrandom",
+ "getrandom 0.2.8",
  "redox_syscall",
- "rust-argon2",
+ "thiserror",
 ]
 
 [[package]]
 name = "regex"
-version = "1.3.9"
+version = "1.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c3780fcf44b193bc4d09f36d2a3c87b251da4a046c87795a0d35f4f927ad8e6"
+checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a"
 dependencies = [
  "aho-corasick",
  "memchr",
  "regex-syntax",
- "thread_local",
+]
+
+[[package]]
+name = "regex-automata"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
+dependencies = [
+ "regex-syntax",
 ]
 
 [[package]]
 name = "regex-syntax"
-version = "0.6.18"
+version = "0.6.28"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8"
+checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
 
 [[package]]
 name = "remove_dir_all"
@@ -2243,13 +2805,13 @@ dependencies = [
 
 [[package]]
 name = "rusoto_core"
-version = "0.45.0"
+version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e977941ee0658df96fca7291ecc6fc9a754600b21ad84b959eb1dbbc9d5abcc7"
+checksum = "1db30db44ea73551326269adcf7a2169428a054f14faf9e1768f2163494f2fa2"
 dependencies = [
  "async-trait",
- "base64 0.12.3",
- "bytes",
+ "base64 0.13.1",
+ "bytes 1.2.1",
  "crc32fast",
  "futures",
  "http",
@@ -2257,46 +2819,41 @@ dependencies = [
  "hyper-tls",
  "lazy_static",
  "log",
- "md5",
- "percent-encoding",
- "pin-project",
  "rusoto_credential",
  "rusoto_signature",
  "rustc_version",
  "serde",
  "serde_json",
- "tokio",
+ "tokio 1.21.2",
  "xml-rs",
 ]
 
 [[package]]
 name = "rusoto_credential"
-version = "0.45.0"
+version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09ac05563f83489b19b4d413607a30821ab08bbd9007d14fa05618da3ef09d8b"
+checksum = "ee0a6c13db5aad6047b6a44ef023dbbc21a056b6dab5be3b79ce4283d5c02d05"
 dependencies = [
  "async-trait",
  "chrono",
- "dirs",
+ "dirs-next",
  "futures",
  "hyper",
- "pin-project",
- "regex",
  "serde",
  "serde_json",
  "shlex",
- "tokio",
+ "tokio 1.21.2",
  "zeroize",
 ]
 
 [[package]]
 name = "rusoto_s3"
-version = "0.45.0"
+version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1146e37a7c1df56471ea67825fe09bbbd37984b5f6e201d8b2e0be4ee15643d8"
+checksum = "7aae4677183411f6b0b412d66194ef5403293917d66e70ab118f07cc24c5b14d"
 dependencies = [
  "async-trait",
- "bytes",
+ "bytes 1.2.1",
  "futures",
  "rusoto_core",
  "xml-rs",
@@ -2304,89 +2861,78 @@ dependencies = [
 
 [[package]]
 name = "rusoto_signature"
-version = "0.45.0"
+version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "97a740a88dde8ded81b6f2cff9cd5e054a5a2e38a38397260f7acdd2c85d17dd"
+checksum = "a5ae95491c8b4847931e291b151127eccd6ff8ca13f33603eb3d0035ecb05272"
 dependencies = [
- "base64 0.12.3",
- "bytes",
+ "base64 0.13.1",
+ "bytes 1.2.1",
+ "chrono",
+ "digest 0.9.0",
  "futures",
  "hex",
  "hmac",
  "http",
  "hyper",
  "log",
- "md5",
+ "md-5",
  "percent-encoding",
- "pin-project",
+ "pin-project-lite 0.2.9",
  "rusoto_credential",
  "rustc_version",
  "serde",
  "sha2",
- "time 0.2.16",
- "tokio",
-]
-
-[[package]]
-name = "rust-argon2"
-version = "0.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9dab61250775933275e84053ac235621dfb739556d5c54a2f2e9313b7cf43a19"
-dependencies = [
- "base64 0.12.3",
- "blake2b_simd",
- "constant_time_eq",
- "crossbeam-utils",
+ "tokio 1.21.2",
 ]
 
 [[package]]
 name = "rustc-demangle"
-version = "0.1.16"
+version = "0.1.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
+checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342"
 
 [[package]]
 name = "rustc_version"
-version = "0.2.3"
+version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
+checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
 dependencies = [
  "semver",
 ]
 
 [[package]]
 name = "ryu"
-version = "1.0.5"
+version = "1.0.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
+checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
 
 [[package]]
 name = "schannel"
-version = "0.1.19"
+version = "0.1.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75"
+checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2"
 dependencies = [
  "lazy_static",
- "winapi 0.3.9",
+ "windows-sys 0.36.1",
 ]
 
-[[package]]
-name = "scoped-tls"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
-
 [[package]]
 name = "scopeguard"
 version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
 
+[[package]]
+name = "scratch"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898"
+
 [[package]]
 name = "security-framework"
-version = "0.4.4"
+version = "2.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "64808902d7d99f78eaddd2b4e2509713babc3dc3c85ad6f4c447680f3c01e535"
+checksum = "2bc1bb97804af6631813c55739f771071e0f2ed33ee20b68c86ec505d906356c"
 dependencies = [
  "bitflags",
  "core-foundation",
@@ -2397,9 +2943,9 @@ dependencies = [
 
 [[package]]
 name = "security-framework-sys"
-version = "0.4.3"
+version = "2.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "17bf11d99252f512695eb468de5516e5cf75455521e69dfe343f3b74e4748405"
+checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556"
 dependencies = [
  "core-foundation-sys",
  "libc",
@@ -2407,39 +2953,24 @@ dependencies = [
 
 [[package]]
 name = "semver"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
-dependencies = [
- "semver-parser",
-]
-
-[[package]]
-name = "semver-parser"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
-
-[[package]]
-name = "send_wrapper"
-version = "0.4.0"
+version = "1.0.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0"
+checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4"
 
 [[package]]
 name = "serde"
-version = "1.0.115"
+version = "1.0.147"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e54c9a88f2da7238af84b5101443f0c0d0a3bbdc455e34a5c9497b1903ed55d5"
+checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965"
 dependencies = [
  "serde_derive",
 ]
 
 [[package]]
 name = "serde_derive"
-version = "1.0.115"
+version = "1.0.147"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "609feed1d0a73cc36a0182a840a9b37b4a82f0b1150369f0536a9e3f2a31dc48"
+checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -2448,11 +2979,11 @@ dependencies = [
 
 [[package]]
 name = "serde_json"
-version = "1.0.57"
+version = "1.0.87"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "164eacbdb13512ec2745fb09d51fd5b22b0d65ed294a1dcf7285a360c80a675c"
+checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45"
 dependencies = [
- "itoa",
+ "itoa 1.0.4",
  "ryu",
  "serde",
 ]
@@ -2464,75 +2995,119 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97"
 dependencies = [
  "dtoa",
- "itoa",
+ "itoa 0.4.8",
  "serde",
  "url",
 ]
 
 [[package]]
-name = "sha-1"
-version = "0.8.2"
+name = "serde_urlencoded"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
+dependencies = [
+ "form_urlencoded",
+ "itoa 1.0.4",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "serde_yaml"
+version = "0.9.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6d232d893b10de3eb7258ff01974d6ee20663d8e833263c99409d4b13a0209da"
+dependencies = [
+ "indexmap",
+ "itoa 1.0.4",
+ "ryu",
+ "serde",
+ "unsafe-libyaml",
+]
+
+[[package]]
+name = "sha1"
+version = "0.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df"
+checksum = "c1da05c97445caa12d05e848c4a4fcbbea29e748ac28f7e80e9b010392063770"
 dependencies = [
- "block-buffer 0.7.3",
- "digest 0.8.1",
- "fake-simd",
- "opaque-debug 0.2.3",
+ "sha1_smol",
 ]
 
 [[package]]
 name = "sha1"
-version = "0.6.0"
+version = "0.10.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3"
+dependencies = [
+ "cfg-if 1.0.0",
+ "cpufeatures",
+ "digest 0.10.5",
+]
+
+[[package]]
+name = "sha1_smol"
+version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d"
+checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012"
 
 [[package]]
 name = "sha2"
-version = "0.9.1"
+version = "0.9.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2933378ddfeda7ea26f48c555bdad8bb446bf8a3d17832dc83e380d444cfb8c1"
+checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800"
 dependencies = [
  "block-buffer 0.9.0",
- "cfg-if",
- "cpuid-bool",
+ "cfg-if 1.0.0",
+ "cpufeatures",
  "digest 0.9.0",
- "opaque-debug 0.3.0",
+ "opaque-debug",
+]
+
+[[package]]
+name = "sharded-slab"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31"
+dependencies = [
+ "lazy_static",
 ]
 
 [[package]]
 name = "shlex"
-version = "0.1.1"
+version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
+checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3"
 
 [[package]]
 name = "signal-hook-registry"
-version = "1.2.1"
+version = "1.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a3e12110bc539e657a646068aaf5eb5b63af9d0c1f7b29c97113fad80e15f035"
+checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0"
 dependencies = [
- "arc-swap",
  "libc",
 ]
 
 [[package]]
 name = "slab"
-version = "0.4.2"
+version = "0.4.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
+checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef"
+dependencies = [
+ "autocfg",
+]
 
 [[package]]
 name = "smallvec"
-version = "1.4.2"
+version = "1.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fbee7696b84bbf3d89a1c2eccff0850e3047ed46bfcd2e92c29a2d074d57e252"
+checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
 
 [[package]]
 name = "snafu"
-version = "0.6.8"
+version = "0.6.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c7f5aed652511f5c9123cf2afbe9c244c29db6effa2abb05c866e965c82405ce"
+checksum = "eab12d3c261b2308b0d80c26fffb58d17eba81a4be97890101f416b478c79ca7"
 dependencies = [
  "doc-comment",
  "snafu-derive",
@@ -2540,9 +3115,9 @@ dependencies = [
 
 [[package]]
 name = "snafu-derive"
-version = "0.6.8"
+version = "0.6.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ebf8f7d5720104a9df0f7076a8682024e958bba0fe9848767bb44f251f3648e9"
+checksum = "1508efa03c362e23817f96cde18abed596a25219a8b2c66e8db33c03543d315b"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -2551,74 +3126,25 @@ dependencies = [
 
 [[package]]
 name = "socket2"
-version = "0.3.12"
+version = "0.3.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "03088793f677dce356f3ccc2edb1b314ad191ab702a5de3faf49304f7e104918"
+checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e"
 dependencies = [
- "cfg-if",
+ "cfg-if 1.0.0",
  "libc",
- "redox_syscall",
  "winapi 0.3.9",
 ]
 
 [[package]]
-name = "standback"
-version = "0.2.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "33a71ea1ea5f8747d1af1979bfb7e65c3a025a70609f04ceb78425bc5adad8e6"
-dependencies = [
- "version_check",
-]
-
-[[package]]
-name = "stdweb"
-version = "0.4.20"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5"
-dependencies = [
- "discard",
- "rustc_version",
- "stdweb-derive",
- "stdweb-internal-macros",
- "stdweb-internal-runtime",
- "wasm-bindgen",
-]
-
-[[package]]
-name = "stdweb-derive"
-version = "0.5.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef"
-dependencies = [
- "proc-macro2",
- "quote",
- "serde",
- "serde_derive",
- "syn",
-]
-
-[[package]]
-name = "stdweb-internal-macros"
-version = "0.2.9"
+name = "socket2"
+version = "0.4.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11"
+checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd"
 dependencies = [
- "base-x",
- "proc-macro2",
- "quote",
- "serde",
- "serde_derive",
- "serde_json",
- "sha1",
- "syn",
+ "libc",
+ "winapi 0.3.9",
 ]
 
-[[package]]
-name = "stdweb-internal-runtime"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0"
-
 [[package]]
 name = "strsim"
 version = "0.10.0"
@@ -2627,26 +3153,32 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
 
 [[package]]
 name = "subtle"
-version = "2.2.3"
+version = "2.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "502d53007c02d7605a05df1c1a73ee436952781653da5d0bf57ad608f66932c1"
+checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
 
 [[package]]
 name = "syn"
-version = "1.0.38"
+version = "1.0.103"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e69abc24912995b3038597a7a593be5053eb0fb44f3cc5beec0deb421790c1f4"
+checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d"
 dependencies = [
  "proc-macro2",
  "quote",
- "unicode-xid",
+ "unicode-ident",
 ]
 
+[[package]]
+name = "sync_wrapper"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "20518fe4a4c9acf048008599e464deb21beeae3d3578418951a189c235a7a9a8"
+
 [[package]]
 name = "synstructure"
-version = "0.12.4"
+version = "0.12.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701"
+checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -2656,13 +3188,13 @@ dependencies = [
 
 [[package]]
 name = "tempfile"
-version = "3.1.0"
+version = "3.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
+checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4"
 dependencies = [
- "cfg-if",
+ "cfg-if 1.0.0",
+ "fastrand",
  "libc",
- "rand",
  "redox_syscall",
  "remove_dir_all",
  "winapi 0.3.9",
@@ -2670,36 +3202,33 @@ dependencies = [
 
 [[package]]
 name = "termcolor"
-version = "1.1.0"
+version = "1.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f"
+checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
 dependencies = [
  "winapi-util",
 ]
 
 [[package]]
 name = "textwrap"
-version = "0.12.1"
+version = "0.16.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "203008d98caf094106cfaba70acfed15e18ed3ddb7d94e49baec153a2b462789"
-dependencies = [
- "unicode-width",
-]
+checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d"
 
 [[package]]
 name = "thiserror"
-version = "1.0.21"
+version = "1.0.37"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "318234ffa22e0920fe9a40d7b8369b5f649d490980cf7aadcf1eb91594869b42"
+checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e"
 dependencies = [
  "thiserror-impl",
 ]
 
 [[package]]
 name = "thiserror-impl"
-version = "1.0.21"
+version = "1.0.37"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cae2447b6282786c3493999f40a9be2a6ad20cb8bd268b0a0dbf5a065535c0ab"
+checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -2708,11 +3237,11 @@ dependencies = [
 
 [[package]]
 name = "thread_local"
-version = "1.0.1"
+version = "1.1.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
+checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180"
 dependencies = [
- "lazy_static",
+ "once_cell",
 ]
 
 [[package]]
@@ -2726,86 +3255,113 @@ dependencies = [
 
 [[package]]
 name = "time"
-version = "0.1.43"
+version = "0.1.44"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438"
+checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
 dependencies = [
  "libc",
+ "wasi 0.10.0+wasi-snapshot-preview1",
  "winapi 0.3.9",
 ]
 
 [[package]]
 name = "time"
-version = "0.2.16"
+version = "0.3.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3a51cadc5b1eec673a685ff7c33192ff7b7603d0b75446fb354939ee615acb15"
+checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376"
 dependencies = [
- "cfg-if",
- "libc",
- "standback",
- "stdweb",
+ "itoa 1.0.4",
+ "serde",
+ "time-core",
  "time-macros",
- "version_check",
- "winapi 0.3.9",
 ]
 
 [[package]]
-name = "time-macros"
+name = "time-core"
 version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ae9b6e9f095bc105e183e3cd493d72579be3181ad4004fceb01adbe9eecab2d"
+checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd"
+
+[[package]]
+name = "time-macros"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2"
 dependencies = [
- "proc-macro-hack",
- "time-macros-impl",
+ "time-core",
 ]
 
 [[package]]
-name = "time-macros-impl"
-version = "0.1.1"
+name = "tinyvec"
+version = "1.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e5c3be1edfad6027c69f5491cf4cb310d1a71ecd6af742788c6ff8bced86b8fa"
+checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
 dependencies = [
- "proc-macro-hack",
- "proc-macro2",
- "quote",
- "standback",
- "syn",
+ "tinyvec_macros",
 ]
 
 [[package]]
-name = "tinyvec"
-version = "0.3.3"
+name = "tinyvec_macros"
+version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "53953d2d3a5ad81d9f844a32f14ebb121f50b650cd59d0ee2a07cf13c617efed"
+checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
 
 [[package]]
 name = "tokio"
-version = "0.2.22"
+version = "0.2.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5d34ca54d84bf2b5b4d7d31e901a8464f7b60ac145a284fba25ceb801f2ddccd"
+checksum = "6703a273949a90131b290be1fe7b039d0fc884aa1935860dfcbe056f28cd8092"
 dependencies = [
- "bytes",
- "fnv",
+ "bytes 0.5.6",
  "futures-core",
  "iovec",
  "lazy_static",
  "libc",
  "memchr",
- "mio",
- "mio-named-pipes",
+ "mio 0.6.23",
  "mio-uds",
- "pin-project-lite 0.1.7",
+ "pin-project-lite 0.1.12",
  "signal-hook-registry",
  "slab",
+ "winapi 0.3.9",
+]
+
+[[package]]
+name = "tokio"
+version = "1.21.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a9e03c497dc955702ba729190dc4aac6f2a0ce97f913e5b1b5912fc5039d9099"
+dependencies = [
+ "autocfg",
+ "bytes 1.2.1",
+ "libc",
+ "memchr",
+ "mio 0.8.5",
+ "num_cpus",
+ "parking_lot 0.12.1",
+ "pin-project-lite 0.2.9",
+ "signal-hook-registry",
+ "socket2 0.4.7",
  "tokio-macros",
+ "tracing",
  "winapi 0.3.9",
 ]
 
+[[package]]
+name = "tokio-io-timeout"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf"
+dependencies = [
+ "pin-project-lite 0.2.9",
+ "tokio 1.21.2",
+]
+
 [[package]]
 name = "tokio-macros"
-version = "0.2.5"
+version = "1.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0c3acc6aa564495a0f2e1d59fab677cd7f81a19994cfc7f3ad0e64301560389"
+checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -2813,27 +3369,38 @@ dependencies = [
 ]
 
 [[package]]
-name = "tokio-tar"
-version = "0.2.0"
+name = "tokio-native-tls"
+version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3a9e415c93375be93253134543229563114a2be8d46440d6d8f25b2ec62a7fb"
+checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b"
 dependencies = [
- "filetime",
- "futures-core",
- "libc",
- "redox_syscall",
- "tokio",
- "xattr",
+ "native-tls",
+ "tokio 1.21.2",
 ]
 
 [[package]]
-name = "tokio-tls"
-version = "0.3.1"
+name = "tokio-stream"
+version = "0.1.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a70f4fcd7b3b24fb194f837560168208f669ca8cb70d0c4b862944452396343"
+checksum = "d660770404473ccd7bc9f8b28494a811bc18542b915c0855c51e8f419d5223ce"
 dependencies = [
- "native-tls",
- "tokio",
+ "futures-core",
+ "pin-project-lite 0.2.9",
+ "tokio 1.21.2",
+]
+
+[[package]]
+name = "tokio-tar"
+version = "0.3.0"
+source = "git+https://github.com/vorot93/tokio-tar.git?rev=1bd30fbd1a219e8982571da48eb68f34317d1e15#1bd30fbd1a219e8982571da48eb68f34317d1e15"
+dependencies = [
+ "filetime",
+ "futures-core",
+ "libc",
+ "redox_syscall",
+ "tokio 1.21.2",
+ "tokio-stream",
+ "xattr",
 ]
 
 [[package]]
@@ -2842,12 +3409,12 @@ version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "571da51182ec208780505a32528fc5512a8fe1443ab960b3f2f3ef093cd16930"
 dependencies = [
- "bytes",
+ "bytes 0.5.6",
  "futures-core",
  "futures-sink",
  "log",
- "pin-project-lite 0.1.7",
- "tokio",
+ "pin-project-lite 0.1.12",
+ "tokio 0.2.25",
 ]
 
 [[package]]
@@ -2856,47 +3423,177 @@ version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499"
 dependencies = [
- "bytes",
+ "bytes 0.5.6",
  "futures-core",
  "futures-sink",
  "log",
- "pin-project-lite 0.1.7",
- "tokio",
+ "pin-project-lite 0.1.12",
+ "tokio 0.2.25",
+]
+
+[[package]]
+name = "tokio-util"
+version = "0.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740"
+dependencies = [
+ "bytes 1.2.1",
+ "futures-core",
+ "futures-sink",
+ "pin-project-lite 0.2.9",
+ "tokio 1.21.2",
+ "tracing",
 ]
 
 [[package]]
 name = "toml"
-version = "0.5.6"
+version = "0.5.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a"
+checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7"
 dependencies = [
  "serde",
 ]
 
+[[package]]
+name = "tonic"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "55b9af819e54b8f33d453655bef9b9acc171568fb49523078d0cc4e7484200ec"
+dependencies = [
+ "async-stream",
+ "async-trait",
+ "axum",
+ "base64 0.13.1",
+ "bytes 1.2.1",
+ "futures-core",
+ "futures-util",
+ "h2 0.3.15",
+ "http",
+ "http-body",
+ "hyper",
+ "hyper-timeout",
+ "percent-encoding",
+ "pin-project 1.0.12",
+ "prost",
+ "prost-derive",
+ "tokio 1.21.2",
+ "tokio-stream",
+ "tokio-util 0.7.4",
+ "tower",
+ "tower-layer",
+ "tower-service",
+ "tracing",
+ "tracing-futures",
+]
+
+[[package]]
+name = "tower"
+version = "0.4.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c"
+dependencies = [
+ "futures-core",
+ "futures-util",
+ "indexmap",
+ "pin-project 1.0.12",
+ "pin-project-lite 0.2.9",
+ "rand 0.8.5",
+ "slab",
+ "tokio 1.21.2",
+ "tokio-util 0.7.4",
+ "tower-layer",
+ "tower-service",
+ "tracing",
+]
+
+[[package]]
+name = "tower-http"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c530c8675c1dbf98facee631536fa116b5fb6382d7dd6dc1b118d970eafe3ba"
+dependencies = [
+ "bitflags",
+ "bytes 1.2.1",
+ "futures-core",
+ "futures-util",
+ "http",
+ "http-body",
+ "http-range-header",
+ "pin-project-lite 0.2.9",
+ "tower",
+ "tower-layer",
+ "tower-service",
+]
+
+[[package]]
+name = "tower-layer"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0"
+
 [[package]]
 name = "tower-service"
-version = "0.3.0"
+version = "0.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e987b6bf443f4b5b3b6f38704195592cca41c5bb7aedd3c3693c7081f8289860"
+checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
 
 [[package]]
 name = "tracing"
-version = "0.1.19"
+version = "0.1.37"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d79ca061b032d6ce30c660fded31189ca0b9922bf483cd70759f13a2d86786c"
+checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
 dependencies = [
- "cfg-if",
+ "cfg-if 1.0.0",
  "log",
+ "pin-project-lite 0.2.9",
+ "tracing-attributes",
  "tracing-core",
 ]
 
+[[package]]
+name = "tracing-attributes"
+version = "0.1.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
 [[package]]
 name = "tracing-core"
-version = "0.1.14"
+version = "0.1.30"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "db63662723c316b43ca36d833707cc93dff82a02ba3d7e354f342682cc8b3545"
+checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a"
 dependencies = [
- "lazy_static",
+ "once_cell",
+ "valuable",
+]
+
+[[package]]
+name = "tracing-futures"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2"
+dependencies = [
+ "pin-project 1.0.12",
+ "tracing",
+]
+
+[[package]]
+name = "tracing-subscriber"
+version = "0.3.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70"
+dependencies = [
+ "matchers",
+ "once_cell",
+ "regex",
+ "sharded-slab",
+ "thread_local",
+ "tracing",
+ "tracing-core",
 ]
 
 [[package]]
@@ -2909,13 +3606,13 @@ dependencies = [
  "enum-as-inner",
  "failure",
  "futures",
- "idna",
+ "idna 0.2.3",
  "lazy_static",
  "log",
- "rand",
+ "rand 0.7.3",
  "smallvec",
- "socket2",
- "tokio",
+ "socket2 0.3.19",
+ "tokio 0.2.25",
  "url",
 ]
 
@@ -2925,7 +3622,7 @@ version = "0.18.0-alpha.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6f90b1502b226f8b2514c6d5b37bafa8c200d7ca4102d57dc36ee0f3b7a04a2f"
 dependencies = [
- "cfg-if",
+ "cfg-if 0.1.10",
  "failure",
  "futures",
  "ipconfig",
@@ -2934,7 +3631,7 @@ dependencies = [
  "lru-cache",
  "resolv-conf",
  "smallvec",
- "tokio",
+ "tokio 0.2.25",
  "trust-dns-proto",
 ]
 
@@ -2946,21 +3643,21 @@ checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
 
 [[package]]
 name = "typenum"
-version = "1.12.0"
+version = "1.15.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
+checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
 
 [[package]]
 name = "ucd-trie"
-version = "0.1.3"
+version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
+checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81"
 
 [[package]]
 name = "uncased"
-version = "0.9.3"
+version = "0.9.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "369fa7fd7969c5373541d3c9a40dc1b76ce676fc87aba30d87c0ad3b97fad179"
+checksum = "09b01702b0fd0b3fadcf98e098780badda8742d4f4a7676615cad90e8ac73622"
 dependencies = [
  "version_check",
 ]
@@ -2976,80 +3673,81 @@ dependencies = [
 
 [[package]]
 name = "unicode-bidi"
-version = "0.3.4"
+version = "0.3.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
-dependencies = [
- "matches",
-]
+checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
 
 [[package]]
 name = "unicode-normalization"
-version = "0.1.13"
+version = "0.1.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6fb19cf769fa8c6a80a162df694621ebeb4dafb606470b2b2fce0be40a98a977"
+checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
 dependencies = [
  "tinyvec",
 ]
 
-[[package]]
-name = "unicode-segmentation"
-version = "1.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0"
-
 [[package]]
 name = "unicode-width"
-version = "0.1.8"
+version = "0.1.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
+checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
 
 [[package]]
 name = "unicode-xid"
-version = "0.2.1"
+version = "0.2.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
+checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
 
 [[package]]
-name = "unindent"
-version = "0.1.6"
+name = "unsafe-libyaml"
+version = "0.2.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "af41d708427f8fd0e915dcebb2cae0f0e6acb2a939b2d399c265c39a38a18942"
+checksum = "c1e5fa573d8ac5f1a856f8d7be41d390ee973daf97c806b2c1a465e4e1406e68"
 
 [[package]]
 name = "url"
-version = "2.1.1"
+version = "2.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "829d4a8476c35c9bf0bbce5a3b23f4106f79728039b726d292bb93bc106787cb"
+checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643"
 dependencies = [
- "idna",
- "matches",
+ "form_urlencoded",
+ "idna 0.3.0",
  "percent-encoding",
 ]
 
 [[package]]
-name = "vcpkg"
-version = "0.2.10"
+name = "valuable"
+version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6454029bf181f092ad1b853286f23e2c507d8e8194d01d92da4a55c274a5508c"
+checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
 
 [[package]]
-name = "vec-arena"
-version = "0.5.2"
+name = "value-bag"
+version = "1.0.0-alpha.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8cb18268690309760d59ee1a9b21132c126ba384f374c59a94db4bc03adeb561"
+checksum = "2209b78d1249f7e6f3293657c9779fe31ced465df091bbd433a1cf88e916ec55"
+dependencies = [
+ "ctor",
+ "version_check",
+]
 
 [[package]]
-name = "vec_map"
-version = "0.8.2"
+name = "vcpkg"
+version = "0.2.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
+checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
 
 [[package]]
 name = "version_check"
-version = "0.9.2"
+version = "0.9.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
+checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
 
 [[package]]
 name = "waker-fn"
@@ -3073,25 +3771,37 @@ version = "0.9.0+wasi-snapshot-preview1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
 
+[[package]]
+name = "wasi"
+version = "0.10.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
+
+[[package]]
+name = "wasi"
+version = "0.11.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+
 [[package]]
 name = "wasm-bindgen"
-version = "0.2.67"
+version = "0.2.83"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0563a9a4b071746dd5aedbc3a28c6fe9be4586fb3fbadb67c400d4f53c6b16c"
+checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268"
 dependencies = [
- "cfg-if",
+ "cfg-if 1.0.0",
  "wasm-bindgen-macro",
 ]
 
 [[package]]
 name = "wasm-bindgen-backend"
-version = "0.2.67"
+version = "0.2.83"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bc71e4c5efa60fb9e74160e89b93353bc24059999c0ae0fb03affc39770310b0"
+checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142"
 dependencies = [
  "bumpalo",
- "lazy_static",
  "log",
+ "once_cell",
  "proc-macro2",
  "quote",
  "syn",
@@ -3100,11 +3810,11 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-futures"
-version = "0.4.17"
+version = "0.4.33"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "95f8d235a77f880bcef268d379810ea6c0af2eacfa90b1ad5af731776e0c4699"
+checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d"
 dependencies = [
- "cfg-if",
+ "cfg-if 1.0.0",
  "js-sys",
  "wasm-bindgen",
  "web-sys",
@@ -3112,9 +3822,9 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-macro"
-version = "0.2.67"
+version = "0.2.83"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "97c57cefa5fa80e2ba15641578b44d36e7a64279bc5ed43c6dbaf329457a2ed2"
+checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810"
 dependencies = [
  "quote",
  "wasm-bindgen-macro-support",
@@ -3122,9 +3832,9 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-macro-support"
-version = "0.2.67"
+version = "0.2.83"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "841a6d1c35c6f596ccea1f82504a192a60378f64b3bb0261904ad8f2f5657556"
+checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -3135,34 +3845,34 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-shared"
-version = "0.2.67"
+version = "0.2.83"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "93b162580e34310e5931c4b792560108b10fd14d64915d7fff8ff00180e70092"
+checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f"
 
 [[package]]
 name = "web-sys"
-version = "0.3.44"
+version = "0.3.60"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dda38f4e5ca63eda02c059d243aa25b5f35ab98451e518c51612cd0f1bd19a47"
+checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f"
 dependencies = [
  "js-sys",
  "wasm-bindgen",
 ]
 
 [[package]]
-name = "wepoll-sys-stjepang"
-version = "1.0.6"
+name = "wepoll-ffi"
+version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6fd319e971980166b53e17b1026812ad66c6b54063be879eb182342b55284694"
+checksum = "d743fdedc5c64377b5fc2bc036b01c7fd642205a0d96356034ae3404d49eb7fb"
 dependencies = [
  "cc",
 ]
 
 [[package]]
 name = "widestring"
-version = "0.4.2"
+version = "0.4.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a763e303c0e0f23b0da40888724762e802a8ffefbc22de4127ef42493c2ea68c"
+checksum = "c168940144dd21fd8046987c16a46a33d5fc84eec29ef9dcddc2ac9e31526b7c"
 
 [[package]]
 name = "winapi"
@@ -3207,6 +3917,106 @@ version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
 
+[[package]]
+name = "windows-sys"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2"
+dependencies = [
+ "windows_aarch64_msvc 0.36.1",
+ "windows_i686_gnu 0.36.1",
+ "windows_i686_msvc 0.36.1",
+ "windows_x86_64_gnu 0.36.1",
+ "windows_x86_64_msvc 0.36.1",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
+dependencies = [
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc 0.42.0",
+ "windows_i686_gnu 0.42.0",
+ "windows_i686_msvc 0.42.0",
+ "windows_x86_64_gnu 0.42.0",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc 0.42.0",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5"
+
 [[package]]
 name = "winreg"
 version = "0.6.2"
@@ -3228,27 +4038,65 @@ dependencies = [
 
 [[package]]
 name = "xattr"
-version = "0.2.2"
+version = "0.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c"
+checksum = "6d1526bbe5aaeb5eb06885f4d987bcdfa5e23187055de9b83fe00156a821fabc"
 dependencies = [
  "libc",
 ]
 
+[[package]]
+name = "xdg"
+version = "2.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0c4583db5cbd4c4c0303df2d15af80f0539db703fa1c68802d4cbbd2dd0f88f6"
+dependencies = [
+ "dirs",
+]
+
 [[package]]
 name = "xml-rs"
-version = "0.8.3"
+version = "0.8.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b07db065a5cf61a7e4ba64f29e67db906fb1787316516c4e6e5ff0fea1efcd8a"
+checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3"
 
 [[package]]
 name = "yansi"
-version = "0.5.0"
+version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9fc79f4a1e39857fc00c3f662cbf2651c771f00e9c15fe2abc341806bd46bd71"
+checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec"
 
 [[package]]
 name = "zeroize"
-version = "1.1.0"
+version = "1.5.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3cbac2ed2ba24cc90f5e06485ac8c7c1e5449fe8911aef4d8877218af021a5b8"
+checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f"
+
+[[package]]
+name = "zstd"
+version = "0.11.2+zstd.1.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4"
+dependencies = [
+ "zstd-safe",
+]
+
+[[package]]
+name = "zstd-safe"
+version = "5.0.2+zstd.1.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db"
+dependencies = [
+ "libc",
+ "zstd-sys",
+]
+
+[[package]]
+name = "zstd-sys"
+version = "2.0.1+zstd.1.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9fd07cbbc53846d9145dbffdf6dd09a7a0aa52be46741825f5c97bdd4f73f12b"
+dependencies = [
+ "cc",
+ "libc",
+]
diff --git a/Cargo.toml b/Cargo.toml
index a468e9d..735fcf8 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -7,18 +7,20 @@ edition = "2018"
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 [dependencies]
-actix = "0.9.0"
-actix-web = "2.0.0"
-actix-rt = "1.0"
+actix = "0.13"
+actix-web = "4.2"
+actix-rt = "2.6"
+actix-files = "0.6"
+actix-service = "2.0"
+async-recursion = "1.0"
 bitflags = "1.2.1"
 actix-http = "1.0.1"
 mime_guess = "2.0.3"
 mime = "0.3.16"
 futures-util = "0.3.5"
-actix-service = "1.0.6"
 percent-encoding = "2.1.0"
 futures-core = "0.3.5"
-bytes = "0.5.6"
+bytes = "1.2.1"
 log = "0.4"
 snafu = "0.6.8"
 serde = "1.0.115"
@@ -26,11 +28,11 @@ serde_derive = "1.0.115"
 serde_json = "1.0"
 toml = "0.5"
 pretty_env_logger = "0.4.0"
-rusoto_core = "0.45.0"
-rusoto_s3 = "0.45.0"
-rusoto_credential = "0.45.0"
+rusoto_core = "0.48.0"
+rusoto_s3 = "0.48.0"
+rusoto_credential = "0.48.0"
 async-trait = "0.1.40"
-async-tar = "0.3"
+async-tar = "0.4"
 async-compat = "0.1.3"
 lazy_static = "1.4.0"
 anyhow = "1.0"
@@ -38,21 +40,26 @@ url = "2.1"
 indoc = "1.0"
 handlebars = "3.4"
 regex = "1.3"
-tokio-tar = "0.2.0"
-clap = "3.0.0-beta.2"
+tokio-stream = "0.1"
+clap = { version = "3.1", features = ["derive"]}
+console-subscriber = "0.1.8"
 
 [dependencies.collective]
 git = "https://gitlab.chromabits.com/etcinit/collective.git"
-tag = "0.1.2"
+rev = "d976875136f684e04aa8e5a800d35d5a9c08e480"
 
 [dependencies.tokio]
-version = "0.2"
-features = ["stream", "signal", "macros"]
+version = "1.0"
+features = ["signal", "macros", "fs", "sync", "tracing"]
 
 [dependencies.tokio-util]
-version = "0.3.0"
+version = "0.7"
 features = ["codec"]
 
+[dependencies.tokio-tar]
+git = "https://github.com/vorot93/tokio-tar.git"
+rev = "1bd30fbd1a219e8982571da48eb68f34317d1e15"
+
 [dependencies.async-compression]
-version = "0.3.7"
-features = ["gzip", "tokio-02"]
\ No newline at end of file
+version = "0.3"
+features = ["gzip", "tokio"]
\ No newline at end of file
diff --git a/src/bundle/s3/packager.rs b/src/bundle/s3/packager.rs
index 41dbe13..248127a 100644
--- a/src/bundle/s3/packager.rs
+++ b/src/bundle/s3/packager.rs
@@ -1,5 +1,5 @@
 use crate::bundle::packager::{BundlePackager, Error, Result};
-use async_compression::tokio_02::write::GzipEncoder;
+use async_compression::tokio::write::GzipEncoder;
 use async_trait::async_trait;
 use futures_util::TryStreamExt;
 use rusoto_core::RusotoError;
diff --git a/src/bundle/s3/poller.rs b/src/bundle/s3/poller.rs
index f9ecc25..4dc5523 100644
--- a/src/bundle/s3/poller.rs
+++ b/src/bundle/s3/poller.rs
@@ -2,14 +2,14 @@ use crate::bundle::{
   poller::{BundlePoller, Error, PollResult, Result},
   Bundle,
 };
-use async_compat::CompatExt;
-use async_tar::Archive;
+
 use async_trait::async_trait;
 use rusoto_core::RusotoError;
 use rusoto_s3::{
   GetObjectError, GetObjectRequest, HeadObjectError, HeadObjectRequest, S3Client, S3,
 };
 use snafu::{ResultExt, Snafu};
+use tokio_tar::Archive;
 use std::path::PathBuf;
 
 #[derive(Snafu, Debug)]
@@ -147,13 +147,14 @@ impl BundlePoller for S3BundlePoller {
 
     info!("S3BundlePoller: Unpacking bundle...");
 
+    let stream = get_object_response
+    .body
+    .ok_or(InternalError::S3MissingBody)?
+    .into_async_read();
+
     // TODO: Write temp file to disk.
-    let archive = Archive::new(
-      get_object_response
-        .body
-        .ok_or(InternalError::S3MissingBody)?
-        .into_async_read()
-        .compat(),
+    let mut archive = Archive::new(
+      stream
     );
 
     archive
diff --git a/src/files/chunked.rs b/src/files/chunked.rs
deleted file mode 100644
index f84fdf5..0000000
--- a/src/files/chunked.rs
+++ /dev/null
@@ -1,98 +0,0 @@
-use actix_web::{
-  error::{BlockingError, Error, ErrorInternalServerError},
-  web,
-};
-use bytes::Bytes;
-use futures_core::Stream;
-use futures_util::future::{FutureExt, LocalBoxFuture};
-use io::Seek;
-use std::{
-  cmp,
-  fs::File,
-  future::Future,
-  io,
-  io::Read,
-  pin::Pin,
-  task::{Context, Poll},
-};
-
-fn handle_error(err: BlockingError<io::Error>) -> Error {
-  match err {
-    BlockingError::Error(err) => err.into(),
-    BlockingError::Canceled => ErrorInternalServerError("Unexpected error"),
-  }
-}
-
-#[doc(hidden)]
-/// A helper created from a `std::fs::File` which reads the file
-/// chunk-by-chunk on a `ThreadPool`.
-pub struct ChunkedReadFile {
-  size: u64,
-  offset: u64,
-  file: Option<File>,
-  fut: Option<LocalBoxFuture<'static, Result<(File, Bytes), BlockingError<io::Error>>>>,
-  counter: u64,
-}
-
-impl ChunkedReadFile {
-  pub fn new(
-    size: u64,
-    offset: u64,
-    file: Option<File>,
-    fut: Option<LocalBoxFuture<'static, Result<(File, Bytes), BlockingError<io::Error>>>>,
-    counter: u64,
-  ) -> ChunkedReadFile {
-    ChunkedReadFile {
-      size,
-      offset,
-      file,
-      fut,
-      counter,
-    }
-  }
-}
-
-impl Stream for ChunkedReadFile {
-  type Item = Result<Bytes, Error>;
-
-  fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
-    if let Some(ref mut fut) = self.fut {
-      return match Pin::new(fut).poll(cx) {
-        Poll::Ready(Ok((file, bytes))) => {
-          self.fut.take();
-          self.file = Some(file);
-          self.offset += bytes.len() as u64;
-          self.counter += bytes.len() as u64;
-          Poll::Ready(Some(Ok(bytes)))
-        }
-        Poll::Ready(Err(e)) => Poll::Ready(Some(Err(handle_error(e)))),
-        Poll::Pending => Poll::Pending,
-      };
-    }
-
-    let size = self.size;
-    let offset = self.offset;
-    let counter = self.counter;
-
-    if size == counter {
-      Poll::Ready(None)
-    } else {
-      let mut file = self.file.take().expect("Use after completion");
-      self.fut = Some(
-        web::block(move || {
-          let max_bytes: usize;
-          max_bytes = cmp::min(size.saturating_sub(counter), 65_536) as usize;
-          let mut buf = Vec::with_capacity(max_bytes);
-          file.seek(io::SeekFrom::Start(offset))?;
-          let nbytes = file.by_ref().take(max_bytes as u64).read_to_end(&mut buf)?;
-          if nbytes == 0 {
-            return Err(io::ErrorKind::UnexpectedEof.into());
-          }
-          Ok((file, Bytes::from(buf)))
-        })
-        .boxed_local(),
-      );
-      self.poll_next(cx)
-    }
-  }
-}
diff --git a/src/files/mod.rs b/src/files/mod.rs
index 24a9269..fb2a953 100644
--- a/src/files/mod.rs
+++ b/src/files/mod.rs
@@ -7,7 +7,7 @@ use std::rc::Rc;
 use std::sync::{Arc, RwLock};
 
 use actix_service::boxed::{self, BoxServiceFactory};
-use actix_service::{IntoServiceFactory, ServiceFactory};
+use actix_service::{IntoServiceFactory, ServiceFactory, ServiceFactoryExt};
 use actix_web::dev::{
   AppService, HttpServiceFactory, ResourceDef, ServiceRequest, ServiceResponse,
 };
@@ -18,14 +18,14 @@ use futures_util::future::{ok, FutureExt, LocalBoxFuture};
 use path_context::PathContext;
 use service::FilesService;
 
-mod chunked;
+use self::service::FilesServiceInner;
+
 pub mod directory;
-pub mod named;
+mod named_ext;
 mod pages;
 mod path;
 pub mod path_context;
 mod pathbuf;
-pub mod range;
 mod service;
 
 type HttpNewService = BoxServiceFactory<(), ServiceRequest, ServiceResponse, ActixError, ()>;
@@ -137,12 +137,12 @@ impl Files {
   /// Sets default handler which is used when no matched file could be found.
   pub fn default_handler<F, U>(mut self, f: F) -> Self
   where
-    F: IntoServiceFactory<U>,
+    F: IntoServiceFactory<U, ServiceRequest>,
     U: ServiceFactory<
+      ServiceRequest,
       Config = (),
-      Request = ServiceRequest,
       Response = ServiceResponse,
-      Error = ActixError,
+      Error = actix_web::error::Error,
     > + 'static,
   {
     // create and configure default resource
@@ -170,8 +170,7 @@ impl HttpServiceFactory for Files {
   }
 }
 
-impl ServiceFactory for Files {
-  type Request = ServiceRequest;
+impl ServiceFactory<ServiceRequest> for Files {
   type Response = ServiceResponse;
   type Error = ActixError;
   type Config = ();
@@ -180,7 +179,7 @@ impl ServiceFactory for Files {
   type Future = LocalBoxFuture<'static, Result<Self::Service, Self::InitError>>;
 
   fn new_service(&self, _: ()) -> Self::Future {
-    let mut srv = FilesService::new(
+    let mut inner = FilesServiceInner::new(
       self.directory.clone(),
       self.redirect_to_slash,
       None,
@@ -190,740 +189,742 @@ impl ServiceFactory for Files {
     );
 
     if let Some(ref default) = *self.default.borrow() {
-      default
-        .new_service(())
-        .map(move |result| match result {
+      let fut = default.new_service(());
+
+      Box::pin(async {
+        match fut.await {
           Ok(default) => {
-            srv.set_default(Some(default));
-            Ok(srv)
+            inner.default = Some(default);
+                        Ok(FilesService(Rc::new(inner)))
           }
           Err(_) => Err(()),
-        })
-        .boxed_local()
+        }
+      })
     } else {
-      ok(srv).boxed_local()
+      Box::pin(async move { Ok(FilesService(Rc::new(inner))) })
     }
   }
 }
 
 #[cfg(test)]
 mod tests {
-  use std::fs;
-  use std::ops::Add;
-  use std::{
-    convert::TryInto,
-    time::{Duration, SystemTime},
-  };
-
-  use super::*;
-  use crate::config::{ContentDispositionConfig, IndexStrategyConfig, ServerConfig};
-  use actix_web::guard;
-  use actix_web::http::header::{self, ContentDisposition, DispositionParam, DispositionType};
-  use actix_web::http::{Method, StatusCode};
-  use actix_web::middleware::Compress;
-  use actix_web::test::{self, TestRequest};
-  use actix_web::{web, App, HttpResponse, Responder};
-  use bytes::Bytes;
-  use fs::File;
-  use named::NamedFile;
-
-  fn serve_dir<T: Into<PathBuf>>(path: T) -> Arc<RwLock<Option<PathBuf>>> {
-    Arc::new(RwLock::new(Some(path.into())))
-  }
-
-  #[actix_rt::test]
-  async fn test_if_modified_since_without_if_none_match() {
-    let file = NamedFile::open("Cargo.toml").unwrap();
-    let since = header::HttpDate::from(SystemTime::now().add(Duration::from_secs(60)));
-
-    let req = TestRequest::default()
-      .header(header::IF_MODIFIED_SINCE, since)
-      .to_http_request();
-    let resp = file.respond_to(&req).await.unwrap();
-    assert_eq!(resp.status(), StatusCode::NOT_MODIFIED);
-  }
-
-  #[actix_rt::test]
-  async fn test_if_modified_since_with_if_none_match() {
-    let file = NamedFile::open("Cargo.toml").unwrap();
-    let since = header::HttpDate::from(SystemTime::now().add(Duration::from_secs(60)));
-
-    let req = TestRequest::default()
-      .header(header::IF_NONE_MATCH, "miss_etag")
-      .header(header::IF_MODIFIED_SINCE, since)
-      .to_http_request();
-    let resp = file.respond_to(&req).await.unwrap();
-    assert_ne!(resp.status(), StatusCode::NOT_MODIFIED);
-  }
-
-  #[actix_rt::test]
-  async fn test_named_file_text() {
-    assert!(NamedFile::open("test--").is_err());
-    let mut file = NamedFile::open("Cargo.toml").unwrap();
-    {
-      file.file();
-      let _f: &File = &file;
-    }
-    {
-      let _f: &mut File = &mut file;
-    }
-
-    let req = TestRequest::default().to_http_request();
-    let resp = file.respond_to(&req).await.unwrap();
-    assert_eq!(
-      resp.headers().get(header::CONTENT_TYPE).unwrap(),
-      "text/x-toml"
-    );
-    assert_eq!(
-      resp.headers().get(header::CONTENT_DISPOSITION).unwrap(),
-      "inline; filename=\"Cargo.toml\""
-    );
-  }
-
-  #[actix_rt::test]
-  async fn test_named_file_content_disposition() {
-    assert!(NamedFile::open("test--").is_err());
-    let mut file = NamedFile::open("Cargo.toml").unwrap();
-    {
-      file.file();
-      let _f: &File = &file;
-    }
-    {
-      let _f: &mut File = &mut file;
-    }
-
-    let req = TestRequest::default().to_http_request();
-    let resp = file.respond_to(&req).await.unwrap();
-    assert_eq!(
-      resp.headers().get(header::CONTENT_DISPOSITION).unwrap(),
-      "inline; filename=\"Cargo.toml\""
-    );
-
-    let file = NamedFile::open("Cargo.toml")
-      .unwrap()
-      .disable_content_disposition();
-    let req = TestRequest::default().to_http_request();
-    let resp = file.respond_to(&req).await.unwrap();
-    assert!(resp.headers().get(header::CONTENT_DISPOSITION).is_none());
-  }
-
-  #[actix_rt::test]
-  async fn test_named_file_non_ascii_file_name() {
-    let mut file = NamedFile::from_file(File::open("Cargo.toml").unwrap(), "貨物.toml").unwrap();
-    {
-      file.file();
-      let _f: &File = &file;
-    }
-    {
-      let _f: &mut File = &mut file;
-    }
-
-    let req = TestRequest::default().to_http_request();
-    let resp = file.respond_to(&req).await.unwrap();
-    assert_eq!(
-      resp.headers().get(header::CONTENT_TYPE).unwrap(),
-      "text/x-toml"
-    );
-    assert_eq!(
-      resp.headers().get(header::CONTENT_DISPOSITION).unwrap(),
-      "inline; filename=\"貨物.toml\"; filename*=UTF-8''%E8%B2%A8%E7%89%A9.toml"
-    );
-  }
-
-  #[actix_rt::test]
-  async fn test_named_file_set_content_type() {
-    let mut file = NamedFile::open("Cargo.toml")
-      .unwrap()
-      .set_content_type(mime::TEXT_XML);
-    {
-      file.file();
-      let _f: &File = &file;
-    }
-    {
-      let _f: &mut File = &mut file;
-    }
-
-    let req = TestRequest::default().to_http_request();
-    let resp = file.respond_to(&req).await.unwrap();
-    assert_eq!(
-      resp.headers().get(header::CONTENT_TYPE).unwrap(),
-      "text/xml"
-    );
-    assert_eq!(
-      resp.headers().get(header::CONTENT_DISPOSITION).unwrap(),
-      "inline; filename=\"Cargo.toml\""
-    );
-  }
-
-  #[actix_rt::test]
-  async fn test_named_file_image() {
-    let mut file = NamedFile::open("tests/test.png").unwrap();
-    {
-      file.file();
-      let _f: &File = &file;
-    }
-    {
-      let _f: &mut File = &mut file;
-    }
-
-    let req = TestRequest::default().to_http_request();
-    let resp = file.respond_to(&req).await.unwrap();
-    assert_eq!(
-      resp.headers().get(header::CONTENT_TYPE).unwrap(),
-      "image/png"
-    );
-    assert_eq!(
-      resp.headers().get(header::CONTENT_DISPOSITION).unwrap(),
-      "inline; filename=\"test.png\""
-    );
-  }
-
-  #[actix_rt::test]
-  async fn test_named_file_image_attachment() {
-    let cd = ContentDisposition {
-      disposition: DispositionType::Attachment,
-      parameters: vec![DispositionParam::Filename(String::from("test.png"))],
-    };
-    let mut file = NamedFile::open("tests/test.png")
-      .unwrap()
-      .set_content_disposition(cd);
-    {
-      file.file();
-      let _f: &File = &file;
-    }
-    {
-      let _f: &mut File = &mut file;
-    }
-
-    let req = TestRequest::default().to_http_request();
-    let resp = file.respond_to(&req).await.unwrap();
-    assert_eq!(
-      resp.headers().get(header::CONTENT_TYPE).unwrap(),
-      "image/png"
-    );
-    assert_eq!(
-      resp.headers().get(header::CONTENT_DISPOSITION).unwrap(),
-      "attachment; filename=\"test.png\""
-    );
-  }
-
-  #[actix_rt::test]
-  async fn test_named_file_binary() {
-    let mut file = NamedFile::open("tests/test.binary").unwrap();
-    {
-      file.file();
-      let _f: &File = &file;
-    }
-    {
-      let _f: &mut File = &mut file;
-    }
-
-    let req = TestRequest::default().to_http_request();
-    let resp = file.respond_to(&req).await.unwrap();
-    assert_eq!(
-      resp.headers().get(header::CONTENT_TYPE).unwrap(),
-      "application/octet-stream"
-    );
-    assert_eq!(
-      resp.headers().get(header::CONTENT_DISPOSITION).unwrap(),
-      "attachment; filename=\"test.binary\""
-    );
-  }
-
-  #[actix_rt::test]
-  async fn test_named_file_status_code_text() {
-    let mut file = NamedFile::open("Cargo.toml")
-      .unwrap()
-      .set_status_code(StatusCode::NOT_FOUND);
-    {
-      file.file();
-      let _f: &File = &file;
-    }
-    {
-      let _f: &mut File = &mut file;
-    }
-
-    let req = TestRequest::default().to_http_request();
-    let resp = file.respond_to(&req).await.unwrap();
-    assert_eq!(
-      resp.headers().get(header::CONTENT_TYPE).unwrap(),
-      "text/x-toml"
-    );
-    assert_eq!(
-      resp.headers().get(header::CONTENT_DISPOSITION).unwrap(),
-      "inline; filename=\"Cargo.toml\""
-    );
-    assert_eq!(resp.status(), StatusCode::NOT_FOUND);
-  }
-
-  #[actix_rt::test]
-  async fn test_mime_override() {
-    let mut server_config = ServerConfig::default();
-
-    server_config.index_strategy = Some(IndexStrategyConfig::IndexFiles {
-      filenames: ["Cargo.toml".to_owned()].iter().cloned().collect(),
-    });
-    server_config.mime_disposition = Some(
-      vec![(
-        "text/x-toml".to_owned(),
-        ContentDispositionConfig::Attachment,
-      )]
-      .iter()
-      .cloned()
-      .collect(),
-    );
-
-    let root_path_context = Arc::new((&server_config).try_into().unwrap());
-    let path_contexts = Arc::new(vec![]);
-
-    let mut srv = test::init_service(App::new().service(Files::new(
-      "/",
-      serve_dir("."),
-      root_path_context,
-      path_contexts,
-    )))
-    .await;
-
-    let request = TestRequest::get().uri("/").to_request();
-    let response = test::call_service(&mut srv, request).await;
-    assert_eq!(response.status(), StatusCode::OK);
-
-    let content_disposition = response
-      .headers()
-      .get(header::CONTENT_DISPOSITION)
-      .expect("To have CONTENT_DISPOSITION");
-    let content_disposition = content_disposition
-      .to_str()
-      .expect("Convert CONTENT_DISPOSITION to str");
-    assert_eq!(content_disposition, "attachment; filename=\"Cargo.toml\"");
-  }
-
-  #[actix_rt::test]
-  async fn test_named_file_ranges_status_code() {
-    let mut server_config = ServerConfig::default();
-
-    server_config.index_strategy = Some(IndexStrategyConfig::IndexFiles {
-      filenames: ["Cargo.toml".to_owned()].iter().cloned().collect(),
-    });
-
-    let root_path_context = Arc::new((&server_config).try_into().unwrap());
-    let path_contexts = Arc::new(vec![]);
-
-    let mut srv = test::init_service(App::new().service(Files::new(
-      "/test",
-      serve_dir("."),
-      root_path_context,
-      path_contexts,
-    )))
-    .await;
-
-    // Valid range header
-    let request = TestRequest::get()
-      .uri("/t%65st/Cargo.toml")
-      .header(header::RANGE, "bytes=10-20")
-      .to_request();
-    let response = test::call_service(&mut srv, request).await;
-    assert_eq!(response.status(), StatusCode::PARTIAL_CONTENT);
-
-    // Invalid range header
-    let request = TestRequest::get()
-      .uri("/t%65st/Cargo.toml")
-      .header(header::RANGE, "bytes=1-0")
-      .to_request();
-    let response = test::call_service(&mut srv, request).await;
-
-    assert_eq!(response.status(), StatusCode::RANGE_NOT_SATISFIABLE);
-  }
-
-  #[actix_rt::test]
-  async fn test_named_file_content_range_headers() {
-    let srv = test::start(|| {
-      let root_path_context = Arc::new((&ServerConfig::default()).try_into().unwrap());
-      let path_contexts = Arc::new(vec![]);
-
-      App::new().service(Files::new(
-        "/",
-        serve_dir("."),
-        root_path_context,
-        path_contexts,
-      ))
-    });
-
-    // Valid range header
-    let response = srv
-      .get("/tests/test.binary")
-      .header(header::RANGE, "bytes=10-20")
-      .send()
-      .await
-      .unwrap();
-    let content_range = response.headers().get(header::CONTENT_RANGE).unwrap();
-    assert_eq!(content_range.to_str().unwrap(), "bytes 10-20/100");
-
-    // Invalid range header
-    let response = srv
-      .get("/tests/test.binary")
-      .header(header::RANGE, "bytes=10-5")
-      .send()
-      .await
-      .unwrap();
-    let content_range = response.headers().get(header::CONTENT_RANGE).unwrap();
-    assert_eq!(content_range.to_str().unwrap(), "bytes */100");
-  }
-
-  #[actix_rt::test]
-  async fn test_named_file_content_length_headers() {
-    let srv = test::start(|| {
-      let root_path_context = Arc::new((&ServerConfig::default()).try_into().unwrap());
-      let path_contexts = Arc::new(vec![]);
-
-      App::new().service(Files::new(
-        "/",
-        serve_dir("."),
-        root_path_context,
-        path_contexts,
-      ))
-    });
-
-    // Valid range header
-    let response = srv
-      .get("/tests/test.binary")
-      .header(header::RANGE, "bytes=10-20")
-      .send()
-      .await
-      .unwrap();
-    let content_length = response.headers().get(header::CONTENT_LENGTH).unwrap();
-    assert_eq!(content_length.to_str().unwrap(), "11");
-
-    // Valid range header, starting from 0
-    let response = srv
-      .get("/tests/test.binary")
-      .header(header::RANGE, "bytes=0-20")
-      .send()
-      .await
-      .unwrap();
-    let content_length = response.headers().get(header::CONTENT_LENGTH).unwrap();
-    assert_eq!(content_length.to_str().unwrap(), "21");
-
-    // Without range header
-    let mut response = srv.get("/tests/test.binary").send().await.unwrap();
-    let content_length = response.headers().get(header::CONTENT_LENGTH).unwrap();
-    assert_eq!(content_length.to_str().unwrap(), "100");
-
-    // Should be no transfer-encoding
-    let transfer_encoding = response.headers().get(header::TRANSFER_ENCODING);
-    assert!(transfer_encoding.is_none());
-
-    // Check file contents
-    let bytes = response.body().await.unwrap();
-    let data = Bytes::from(fs::read("tests/test.binary").unwrap());
-    assert_eq!(bytes, data);
-  }
-
-  #[actix_rt::test]
-  async fn test_head_content_length_headers() {
-    let srv = test::start(|| {
-      let root_path_context = Arc::new((&ServerConfig::default()).try_into().unwrap());
-      let path_contexts = Arc::new(vec![]);
-
-      App::new().service(Files::new(
-        "/",
-        serve_dir("."),
-        root_path_context,
-        path_contexts,
-      ))
-    });
-
-    let response = srv.head("/tests/test.binary").send().await.unwrap();
-
-    let content_length = response
-      .headers()
-      .get(header::CONTENT_LENGTH)
-      .unwrap()
-      .to_str()
-      .unwrap();
-
-    assert_eq!(content_length, "100");
-  }
-
-  #[actix_rt::test]
-  async fn test_static_files_with_spaces() {
-    let mut server_config = ServerConfig::default();
-
-    server_config.index_strategy = Some(IndexStrategyConfig::IndexFiles {
-      filenames: ["Cargo.toml".to_owned()].iter().cloned().collect(),
-    });
-
-    let root_path_context = Arc::new((&server_config).try_into().unwrap());
-    let path_contexts = Arc::new(vec![]);
-
-    let mut srv = test::init_service(App::new().service(Files::new(
-      "/",
-      serve_dir("."),
-      root_path_context,
-      path_contexts,
-    )))
-    .await;
-    let request = TestRequest::get()
-      .uri("/tests/test%20space.binary")
-      .to_request();
-    let response = test::call_service(&mut srv, request).await;
-    assert_eq!(response.status(), StatusCode::OK);
-
-    let bytes = test::read_body(response).await;
-    let data = Bytes::from(fs::read("tests/test space.binary").unwrap());
-    assert_eq!(bytes, data);
-  }
-
-  #[actix_rt::test]
-  async fn test_files_not_allowed() {
-    let root_path_context = Arc::new((&ServerConfig::default()).try_into().unwrap());
-    let path_contexts = Arc::new(vec![]);
-
-    let mut srv = test::init_service(App::new().default_service(Files::new(
-      "/",
-      serve_dir("."),
-      root_path_context,
-      path_contexts,
-    )))
-    .await;
-
-    let req = TestRequest::default()
-      .uri("/Cargo.toml")
-      .method(Method::POST)
-      .to_request();
-
-    let resp = test::call_service(&mut srv, req).await;
-    assert_eq!(resp.status(), StatusCode::METHOD_NOT_ALLOWED);
-
-    let root_path_context = Arc::new((&ServerConfig::default()).try_into().unwrap());
-    let path_contexts = Arc::new(vec![]);
-
-    let mut srv = test::init_service(App::new().default_service(Files::new(
-      "/",
-      serve_dir("."),
-      root_path_context,
-      path_contexts,
-    )))
-    .await;
-    let req = TestRequest::default()
-      .method(Method::PUT)
-      .uri("/Cargo.toml")
-      .to_request();
-    let resp = test::call_service(&mut srv, req).await;
-    assert_eq!(resp.status(), StatusCode::METHOD_NOT_ALLOWED);
-  }
-
-  #[actix_rt::test]
-  async fn test_files_guards() {
-    let root_path_context = Arc::new((&ServerConfig::default()).try_into().unwrap());
-    let path_contexts = Arc::new(vec![]);
-
-    let mut srv = test::init_service(App::new().service(
-      Files::new("/", serve_dir("."), root_path_context, path_contexts).use_guards(guard::Post()),
-    ))
-    .await;
-
-    let req = TestRequest::default()
-      .uri("/Cargo.toml")
-      .method(Method::POST)
-      .to_request();
-
-    let resp = test::call_service(&mut srv, req).await;
-    assert_eq!(resp.status(), StatusCode::OK);
-  }
-
-  #[actix_rt::test]
-  async fn test_named_file_content_encoding() {
-    let mut srv = test::init_service(App::new().wrap(Compress::default()).service(
-      web::resource("/").to(|| async {
-        NamedFile::open("Cargo.toml")
-          .unwrap()
-          .set_content_encoding(header::ContentEncoding::Identity)
-      }),
-    ))
-    .await;
-
-    let request = TestRequest::get()
-      .uri("/")
-      .header(header::ACCEPT_ENCODING, "gzip")
-      .to_request();
-    let res = test::call_service(&mut srv, request).await;
-    assert_eq!(res.status(), StatusCode::OK);
-    assert!(!res.headers().contains_key(header::CONTENT_ENCODING));
-  }
-
-  #[actix_rt::test]
-  async fn test_named_file_content_encoding_gzip() {
-    let mut srv = test::init_service(App::new().wrap(Compress::default()).service(
-      web::resource("/").to(|| async {
-        NamedFile::open("Cargo.toml")
-          .unwrap()
-          .set_content_encoding(header::ContentEncoding::Gzip)
-      }),
-    ))
-    .await;
-
-    let request = TestRequest::get()
-      .uri("/")
-      .header(header::ACCEPT_ENCODING, "gzip")
-      .to_request();
-    let res = test::call_service(&mut srv, request).await;
-    assert_eq!(res.status(), StatusCode::OK);
-    assert_eq!(
-      res
-        .headers()
-        .get(header::CONTENT_ENCODING)
-        .unwrap()
-        .to_str()
-        .unwrap(),
-      "gzip"
-    );
-  }
-
-  #[actix_rt::test]
-  async fn test_named_file_allowed_method() {
-    let req = TestRequest::default().method(Method::GET).to_http_request();
-    let file = NamedFile::open("Cargo.toml").unwrap();
-    let resp = file.respond_to(&req).await.unwrap();
-    assert_eq!(resp.status(), StatusCode::OK);
-  }
-
-  #[actix_rt::test]
-  async fn test_static_files() {
-    let mut server_config = ServerConfig::default();
-
-    server_config.index_strategy = Some(IndexStrategyConfig::AlwaysShowListing);
-
-    let root_path_context = Arc::new((&server_config).try_into().unwrap());
-    let path_contexts = Arc::new(vec![]);
-
-    let mut srv = test::init_service(App::new().service(Files::new(
-      "/",
-      serve_dir("."),
-      root_path_context,
-      path_contexts,
-    )))
-    .await;
-    let req = TestRequest::with_uri("/missing").to_request();
-
-    let resp = test::call_service(&mut srv, req).await;
-    assert_eq!(resp.status(), StatusCode::NOT_FOUND);
-
-    // Without index strategy.
-    let root_path_context = Arc::new((&ServerConfig::default()).try_into().unwrap());
-    let path_contexts = Arc::new(vec![]);
-
-    let mut srv = test::init_service(App::new().service(Files::new(
-      "/",
-      serve_dir("."),
-      root_path_context,
-      path_contexts,
-    )))
-    .await;
-
-    let req = TestRequest::default().to_request();
-    let resp = test::call_service(&mut srv, req).await;
-    assert_eq!(resp.status(), StatusCode::NOT_FOUND);
-
-    // With default renderer.
-    server_config.index_strategy = Some(IndexStrategyConfig::AlwaysShowListing);
-
-    let root_path_context = Arc::new((&server_config).try_into().unwrap());
-    let path_contexts = Arc::new(vec![]);
-
-    let mut srv = test::init_service(App::new().service(Files::new(
-      "/",
-      serve_dir("."),
-      root_path_context,
-      path_contexts,
-    )))
-    .await;
-    let req = TestRequest::with_uri("/tests").to_request();
-    let resp = test::call_service(&mut srv, req).await;
-    assert_eq!(
-      resp.headers().get(header::CONTENT_TYPE).unwrap(),
-      "text/html; charset=utf-8"
-    );
-
-    let bytes = test::read_body(resp).await;
-    assert!(format!("{:?}", bytes).contains("/tests/test.png"));
-  }
-
-  #[actix_rt::test]
-  async fn test_redirect_to_slash_directory() {
-    let mut server_config = ServerConfig::default();
-
-    server_config.index_strategy = Some(IndexStrategyConfig::IndexFiles {
-      filenames: ["test.png".to_owned()].iter().cloned().collect(),
-    });
-
-    let root_path_context = Arc::new((&server_config).try_into().unwrap());
-    let path_contexts = Arc::new(vec![]);
-
-    // should not redirect if no index
-    // let mut srv = test::init_service(
-    //   App::new().service(Files::new("/", serve_dir(".")).redirect_to_slash_directory()),
-    // )
-    // .await;
-    // let req = TestRequest::with_uri("/tests").to_request();
-    // let resp = test::call_service(&mut srv, req).await;
-    // assert_eq!(resp.status(), StatusCode::NOT_FOUND);
-
-    // should redirect if index present
-    let mut srv = test::init_service(
-      App::new().service(
-        Files::new("/", serve_dir("."), root_path_context, path_contexts)
-          .redirect_to_slash_directory(),
-      ),
-    )
-    .await;
-    let req = TestRequest::with_uri("/tests").to_request();
-    let resp = test::call_service(&mut srv, req).await;
-    assert_eq!(resp.status(), StatusCode::FOUND);
-
-    // should not redirect if the path is wrong
-    let req = TestRequest::with_uri("/not_existing").to_request();
-    let resp = test::call_service(&mut srv, req).await;
-    assert_eq!(resp.status(), StatusCode::NOT_FOUND);
-  }
-
-  #[actix_rt::test]
-  async fn test_static_files_bad_directory() {
-    let root_path_context = Arc::new((&ServerConfig::default()).try_into().unwrap());
-    let path_contexts = Arc::new(vec![]);
-
-    let _st: Files = Files::new("/", serve_dir("missing"), root_path_context, path_contexts);
-
-    let root_path_context = Arc::new((&ServerConfig::default()).try_into().unwrap());
-    let path_contexts = Arc::new(vec![]);
-
-    let _st: Files = Files::new(
-      "/",
-      serve_dir("Cargo.toml"),
-      root_path_context,
-      path_contexts,
-    );
-  }
-
-  #[actix_rt::test]
-  async fn test_default_handler_file_missing() {
-    let root_path_context = Arc::new((&ServerConfig::default()).try_into().unwrap());
-    let path_contexts = Arc::new(vec![]);
-
-    let mut st = Files::new("/", serve_dir("."), root_path_context, path_contexts)
-      .default_handler(|req: ServiceRequest| {
-        ok(req.into_response(HttpResponse::Ok().body("default content")))
-      })
-      .new_service(())
-      .await
-      .unwrap();
-    let req = TestRequest::with_uri("/missing").to_srv_request();
-
-    let resp = test::call_service(&mut st, req).await;
-    assert_eq!(resp.status(), StatusCode::OK);
-    let bytes = test::read_body(resp).await;
-    assert_eq!(bytes, Bytes::from_static(b"default content"));
-  }
+//   use std::fs;
+//   use std::ops::Add;
+//   use std::{
+//     convert::TryInto,
+//     time::{Duration, SystemTime},
+//   };
+
+//   use super::*;
+//   use crate::config::{ContentDispositionConfig, IndexStrategyConfig, ServerConfig};
+//   use actix_files::NamedFile;
+// use actix_web::guard;
+//   use actix_web::http::header::{self, ContentDisposition, DispositionParam, DispositionType};
+//   use actix_web::http::{Method, StatusCode};
+//   use actix_web::middleware::Compress;
+//   use actix_web::test::{self, TestRequest};
+//   use actix_web::{web, App, HttpResponse, Responder};
+//   use bytes::Bytes;
+//   use fs::File;
+
+//   fn serve_dir<T: Into<PathBuf>>(path: T) -> Arc<RwLock<Option<PathBuf>>> {
+//     Arc::new(RwLock::new(Some(path.into())))
+//   }
+
+//   #[actix_rt::test]
+//   async fn test_if_modified_since_without_if_none_match() {
+//     let file = NamedFile::open("Cargo.toml").unwrap();
+//     let since = header::HttpDate::from(SystemTime::now().add(Duration::from_secs(60)));
+
+//     let req = TestRequest::default()
+//       .header(header::IF_MODIFIED_SINCE, since)
+//       .to_http_request();
+//     let resp = file.respond_to(&req).await.unwrap();
+//     assert_eq!(resp.status(), StatusCode::NOT_MODIFIED);
+//   }
+
+//   #[actix_rt::test]
+//   async fn test_if_modified_since_with_if_none_match() {
+//     let file = NamedFile::open("Cargo.toml").unwrap();
+//     let since = header::HttpDate::from(SystemTime::now().add(Duration::from_secs(60)));
+
+//     let req = TestRequest::default()
+//       .header(header::IF_NONE_MATCH, "miss_etag")
+//       .header(header::IF_MODIFIED_SINCE, since)
+//       .to_http_request();
+//     let resp = file.respond_to(&req).await.unwrap();
+//     assert_ne!(resp.status(), StatusCode::NOT_MODIFIED);
+//   }
+
+//   #[actix_rt::test]
+//   async fn test_named_file_text() {
+//     assert!(NamedFile::open("test--").is_err());
+//     let mut file = NamedFile::open("Cargo.toml").unwrap();
+//     {
+//       file.file();
+//       let _f: &File = &file;
+//     }
+//     {
+//       let _f: &mut File = &mut file;
+//     }
+
+//     let req = TestRequest::default().to_http_request();
+//     let resp = file.respond_to(&req).await.unwrap();
+//     assert_eq!(
+//       resp.headers().get(header::CONTENT_TYPE).unwrap(),
+//       "text/x-toml"
+//     );
+//     assert_eq!(
+//       resp.headers().get(header::CONTENT_DISPOSITION).unwrap(),
+//       "inline; filename=\"Cargo.toml\""
+//     );
+//   }
+
+//   #[actix_rt::test]
+//   async fn test_named_file_content_disposition() {
+//     assert!(NamedFile::open("test--").is_err());
+//     let mut file = NamedFile::open("Cargo.toml").unwrap();
+//     {
+//       file.file();
+//       let _f: &File = &file;
+//     }
+//     {
+//       let _f: &mut File = &mut file;
+//     }
+
+//     let req = TestRequest::default().to_http_request();
+//     let resp = file.respond_to(&req).await.unwrap();
+//     assert_eq!(
+//       resp.headers().get(header::CONTENT_DISPOSITION).unwrap(),
+//       "inline; filename=\"Cargo.toml\""
+//     );
+
+//     let file = NamedFile::open("Cargo.toml")
+//       .unwrap()
+//       .disable_content_disposition();
+//     let req = TestRequest::default().to_http_request();
+//     let resp = file.respond_to(&req).await.unwrap();
+//     assert!(resp.headers().get(header::CONTENT_DISPOSITION).is_none());
+//   }
+
+//   #[actix_rt::test]
+//   async fn test_named_file_non_ascii_file_name() {
+//     let mut file = NamedFile::from_file(File::open("Cargo.toml").unwrap(), "貨物.toml").unwrap();
+//     {
+//       file.file();
+//       let _f: &File = &file;
+//     }
+//     {
+//       let _f: &mut File = &mut file;
+//     }
+
+//     let req = TestRequest::default().to_http_request();
+//     let resp = file.respond_to(&req).await.unwrap();
+//     assert_eq!(
+//       resp.headers().get(header::CONTENT_TYPE).unwrap(),
+//       "text/x-toml"
+//     );
+//     assert_eq!(
+//       resp.headers().get(header::CONTENT_DISPOSITION).unwrap(),
+//       "inline; filename=\"貨物.toml\"; filename*=UTF-8''%E8%B2%A8%E7%89%A9.toml"
+//     );
+//   }
+
+//   #[actix_rt::test]
+//   async fn test_named_file_set_content_type() {
+//     let mut file = NamedFile::open("Cargo.toml")
+//       .unwrap()
+//       .set_content_type(mime::TEXT_XML);
+//     {
+//       file.file();
+//       let _f: &File = &file;
+//     }
+//     {
+//       let _f: &mut File = &mut file;
+//     }
+
+//     let req = TestRequest::default().to_http_request();
+//     let resp = file.respond_to(&req).await.unwrap();
+//     assert_eq!(
+//       resp.headers().get(header::CONTENT_TYPE).unwrap(),
+//       "text/xml"
+//     );
+//     assert_eq!(
+//       resp.headers().get(header::CONTENT_DISPOSITION).unwrap(),
+//       "inline; filename=\"Cargo.toml\""
+//     );
+//   }
+
+//   #[actix_rt::test]
+//   async fn test_named_file_image() {
+//     let mut file = NamedFile::open("tests/test.png").unwrap();
+//     {
+//       file.file();
+//       let _f: &File = &file;
+//     }
+//     {
+//       let _f: &mut File = &mut file;
+//     }
+
+//     let req = TestRequest::default().to_http_request();
+//     let resp = file.respond_to(&req).await.unwrap();
+//     assert_eq!(
+//       resp.headers().get(header::CONTENT_TYPE).unwrap(),
+//       "image/png"
+//     );
+//     assert_eq!(
+//       resp.headers().get(header::CONTENT_DISPOSITION).unwrap(),
+//       "inline; filename=\"test.png\""
+//     );
+//   }
+
+//   #[actix_rt::test]
+//   async fn test_named_file_image_attachment() {
+//     let cd = ContentDisposition {
+//       disposition: DispositionType::Attachment,
+//       parameters: vec![DispositionParam::Filename(String::from("test.png"))],
+//     };
+//     let mut file = NamedFile::open("tests/test.png")
+//       .unwrap()
+//       .set_content_disposition(cd);
+//     {
+//       file.file();
+//       let _f: &File = &file;
+//     }
+//     {
+//       let _f: &mut File = &mut file;
+//     }
+
+//     let req = TestRequest::default().to_http_request();
+//     let resp = file.respond_to(&req).await.unwrap();
+//     assert_eq!(
+//       resp.headers().get(header::CONTENT_TYPE).unwrap(),
+//       "image/png"
+//     );
+//     assert_eq!(
+//       resp.headers().get(header::CONTENT_DISPOSITION).unwrap(),
+//       "attachment; filename=\"test.png\""
+//     );
+//   }
+
+//   #[actix_rt::test]
+//   async fn test_named_file_binary() {
+//     let mut file = NamedFile::open("tests/test.binary").unwrap();
+//     {
+//       file.file();
+//       let _f: &File = &file;
+//     }
+//     {
+//       let _f: &mut File = &mut file;
+//     }
+
+//     let req = TestRequest::default().to_http_request();
+//     let resp = file.respond_to(&req).await.unwrap();
+//     assert_eq!(
+//       resp.headers().get(header::CONTENT_TYPE).unwrap(),
+//       "application/octet-stream"
+//     );
+//     assert_eq!(
+//       resp.headers().get(header::CONTENT_DISPOSITION).unwrap(),
+//       "attachment; filename=\"test.binary\""
+//     );
+//   }
+
+//   #[actix_rt::test]
+//   async fn test_named_file_status_code_text() {
+//     let mut file = NamedFile::open("Cargo.toml")
+//       .unwrap()
+//       .set_status_code(StatusCode::NOT_FOUND);
+//     {
+//       file.file();
+//       let _f: &File = &file;
+//     }
+//     {
+//       let _f: &mut File = &mut file;
+//     }
+
+//     let req = TestRequest::default().to_http_request();
+//     let resp = file.respond_to(&req).await.unwrap();
+//     assert_eq!(
+//       resp.headers().get(header::CONTENT_TYPE).unwrap(),
+//       "text/x-toml"
+//     );
+//     assert_eq!(
+//       resp.headers().get(header::CONTENT_DISPOSITION).unwrap(),
+//       "inline; filename=\"Cargo.toml\""
+//     );
+//     assert_eq!(resp.status(), StatusCode::NOT_FOUND);
+//   }
+
+//   #[actix_rt::test]
+//   async fn test_mime_override() {
+//     let mut server_config = ServerConfig::default();
+
+//     server_config.index_strategy = Some(IndexStrategyConfig::IndexFiles {
+//       filenames: ["Cargo.toml".to_owned()].iter().cloned().collect(),
+//     });
+//     server_config.mime_disposition = Some(
+//       vec![(
+//         "text/x-toml".to_owned(),
+//         ContentDispositionConfig::Attachment,
+//       )]
+//       .iter()
+//       .cloned()
+//       .collect(),
+//     );
+
+//     let root_path_context = Arc::new((&server_config).try_into().unwrap());
+//     let path_contexts = Arc::new(vec![]);
+
+//     let mut srv = test::init_service(App::new().service(Files::new(
+//       "/",
+//       serve_dir("."),
+//       root_path_context,
+//       path_contexts,
+//     )))
+//     .await;
+
+//     let request = TestRequest::get().uri("/").to_request();
+//     let response = test::call_service(&mut srv, request).await;
+//     assert_eq!(response.status(), StatusCode::OK);
+
+//     let content_disposition = response
+//       .headers()
+//       .get(header::CONTENT_DISPOSITION)
+//       .expect("To have CONTENT_DISPOSITION");
+//     let content_disposition = content_disposition
+//       .to_str()
+//       .expect("Convert CONTENT_DISPOSITION to str");
+//     assert_eq!(content_disposition, "attachment; filename=\"Cargo.toml\"");
+//   }
+
+//   #[actix_rt::test]
+//   async fn test_named_file_ranges_status_code() {
+//     let mut server_config = ServerConfig::default();
+
+//     server_config.index_strategy = Some(IndexStrategyConfig::IndexFiles {
+//       filenames: ["Cargo.toml".to_owned()].iter().cloned().collect(),
+//     });
+
+//     let root_path_context = Arc::new((&server_config).try_into().unwrap());
+//     let path_contexts = Arc::new(vec![]);
+
+//     let mut srv = test::init_service(App::new().service(Files::new(
+//       "/test",
+//       serve_dir("."),
+//       root_path_context,
+//       path_contexts,
+//     )))
+//     .await;
+
+//     // Valid range header
+//     let request = TestRequest::get()
+//       .uri("/t%65st/Cargo.toml")
+//       .header(header::RANGE, "bytes=10-20")
+//       .to_request();
+//     let response = test::call_service(&mut srv, request).await;
+//     assert_eq!(response.status(), StatusCode::PARTIAL_CONTENT);
+
+//     // Invalid range header
+//     let request = TestRequest::get()
+//       .uri("/t%65st/Cargo.toml")
+//       .header(header::RANGE, "bytes=1-0")
+//       .to_request();
+//     let response = test::call_service(&mut srv, request).await;
+
+//     assert_eq!(response.status(), StatusCode::RANGE_NOT_SATISFIABLE);
+//   }
+
+//   #[actix_rt::test]
+//   async fn test_named_file_content_range_headers() {
+//     let srv = test::init_service(|| {
+//       let root_path_context = Arc::new((&ServerConfig::default()).try_into().unwrap());
+//       let path_contexts = Arc::new(vec![]);
+
+//       App::new().service(Files::new(
+//         "/",
+//         serve_dir("."),
+//         root_path_context,
+//         path_contexts,
+//       ))
+//     });
+
+//     // Valid range header
+//     let response = srv
+//       .get("/tests/test.binary")
+//       .header(header::RANGE, "bytes=10-20")
+//       .send()
+//       .await
+//       .unwrap();
+//     let content_range = response.headers().get(header::CONTENT_RANGE).unwrap();
+//     assert_eq!(content_range.to_str().unwrap(), "bytes 10-20/100");
+
+//     // Invalid range header
+//     let response = srv
+//       .get("/tests/test.binary")
+//       .header(header::RANGE, "bytes=10-5")
+//       .send()
+//       .await
+//       .unwrap();
+//     let content_range = response.headers().get(header::CONTENT_RANGE).unwrap();
+//     assert_eq!(content_range.to_str().unwrap(), "bytes */100");
+//   }
+
+//   #[actix_rt::test]
+//   async fn test_named_file_content_length_headers() {
+//     let srv = test::init_service(|| {
+//       let root_path_context = Arc::new((&ServerConfig::default()).try_into().unwrap());
+//       let path_contexts = Arc::new(vec![]);
+
+//       App::new().service(Files::new(
+//         "/",
+//         serve_dir("."),
+//         root_path_context,
+//         path_contexts,
+//       ))
+//     });
+
+//     // Valid range header
+//     let response = srv
+//       .get("/tests/test.binary")
+//       .header(header::RANGE, "bytes=10-20")
+//       .send()
+//       .await
+//       .unwrap();
+//     let content_length = response.headers().get(header::CONTENT_LENGTH).unwrap();
+//     assert_eq!(content_length.to_str().unwrap(), "11");
+
+//     // Valid range header, starting from 0
+//     let response = srv
+//       .get("/tests/test.binary")
+//       .header(header::RANGE, "bytes=0-20")
+//       .send()
+//       .await
+//       .unwrap();
+//     let content_length = response.headers().get(header::CONTENT_LENGTH).unwrap();
+//     assert_eq!(content_length.to_str().unwrap(), "21");
+
+//     // Without range header
+//     let mut response = srv.get("/tests/test.binary").send().await.unwrap();
+//     let content_length = response.headers().get(header::CONTENT_LENGTH).unwrap();
+//     assert_eq!(content_length.to_str().unwrap(), "100");
+
+//     // Should be no transfer-encoding
+//     let transfer_encoding = response.headers().get(header::TRANSFER_ENCODING);
+//     assert!(transfer_encoding.is_none());
+
+//     // Check file contents
+//     let bytes = response.body().await.unwrap();
+//     let data = Bytes::from(fs::read("tests/test.binary").unwrap());
+    
+//     assert_eq!(bytes, data);
+//   }
+
+//   #[actix_rt::test]
+//   async fn test_head_content_length_headers() {
+//     let srv = test::init_service(|| {
+//       let root_path_context = Arc::new((&ServerConfig::default()).try_into().unwrap());
+//       let path_contexts = Arc::new(vec![]);
+
+//       App::new().service(Files::new(
+//         "/",
+//         serve_dir("."),
+//         root_path_context,
+//         path_contexts,
+//       ))
+//     });
+
+//     let response = srv.head("/tests/test.binary").send().await.unwrap();
+
+//     let content_length = response
+//       .headers()
+//       .get(header::CONTENT_LENGTH)
+//       .unwrap()
+//       .to_str()
+//       .unwrap();
+
+//     assert_eq!(content_length, "100");
+//   }
+
+//   #[actix_rt::test]
+//   async fn test_static_files_with_spaces() {
+//     let mut server_config = ServerConfig::default();
+
+//     server_config.index_strategy = Some(IndexStrategyConfig::IndexFiles {
+//       filenames: ["Cargo.toml".to_owned()].iter().cloned().collect(),
+//     });
+
+//     let root_path_context = Arc::new((&server_config).try_into().unwrap());
+//     let path_contexts = Arc::new(vec![]);
+
+//     let mut srv = test::init_service(App::new().service(Files::new(
+//       "/",
+//       serve_dir("."),
+//       root_path_context,
+//       path_contexts,
+//     )))
+//     .await;
+//     let request = TestRequest::get()
+//       .uri("/tests/test%20space.binary")
+//       .to_request();
+//     let response = test::call_service(&mut srv, request).await;
+//     assert_eq!(response.status(), StatusCode::OK);
+
+//     let bytes = test::read_body(response).await;
+//     let data = Bytes::from(fs::read("tests/test space.binary").unwrap());
+//     assert_eq!(bytes, data);
+//   }
+
+//   #[actix_rt::test]
+//   async fn test_files_not_allowed() {
+//     let root_path_context = Arc::new((&ServerConfig::default()).try_into().unwrap());
+//     let path_contexts = Arc::new(vec![]);
+
+//     let mut srv = test::init_service(App::new().default_service(Files::new(
+//       "/",
+//       serve_dir("."),
+//       root_path_context,
+//       path_contexts,
+//     )))
+//     .await;
+
+//     let req = TestRequest::default()
+//       .uri("/Cargo.toml")
+//       .method(Method::POST)
+//       .to_request();
+
+//     let resp = test::call_service(&mut srv, req).await;
+//     assert_eq!(resp.status(), StatusCode::METHOD_NOT_ALLOWED);
+
+//     let root_path_context = Arc::new((&ServerConfig::default()).try_into().unwrap());
+//     let path_contexts = Arc::new(vec![]);
+
+//     let mut srv = test::init_service(App::new().default_service(Files::new(
+//       "/",
+//       serve_dir("."),
+//       root_path_context,
+//       path_contexts,
+//     )))
+//     .await;
+//     let req = TestRequest::default()
+//       .method(Method::PUT)
+//       .uri("/Cargo.toml")
+//       .to_request();
+//     let resp = test::call_service(&mut srv, req).await;
+//     assert_eq!(resp.status(), StatusCode::METHOD_NOT_ALLOWED);
+//   }
+
+//   #[actix_rt::test]
+//   async fn test_files_guards() {
+//     let root_path_context = Arc::new((&ServerConfig::default()).try_into().unwrap());
+//     let path_contexts = Arc::new(vec![]);
+
+//     let mut srv = test::init_service(App::new().service(
+//       Files::new("/", serve_dir("."), root_path_context, path_contexts).use_guards(guard::Post()),
+//     ))
+//     .await;
+
+//     let req = TestRequest::default()
+//       .uri("/Cargo.toml")
+//       .method(Method::POST)
+//       .to_request();
+
+//     let resp = test::call_service(&mut srv, req).await;
+//     assert_eq!(resp.status(), StatusCode::OK);
+//   }
+
+//   #[actix_rt::test]
+//   async fn test_named_file_content_encoding() {
+//     let mut srv = test::init_service(App::new().wrap(Compress::default()).service(
+//       web::resource("/").to(|| async {
+//         NamedFile::open("Cargo.toml")
+//           .unwrap()
+//           .set_content_encoding(header::ContentEncoding::Identity)
+//       }),
+//     ))
+//     .await;
+
+//     let request = TestRequest::get()
+//       .uri("/")
+//       .header(header::ACCEPT_ENCODING, "gzip")
+//       .to_request();
+//     let res = test::call_service(&mut srv, request).await;
+//     assert_eq!(res.status(), StatusCode::OK);
+//     assert!(!res.headers().contains_key(header::CONTENT_ENCODING));
+//   }
+
+//   #[actix_rt::test]
+//   async fn test_named_file_content_encoding_gzip() {
+//     let mut srv = test::init_service(App::new().wrap(Compress::default()).service(
+//       web::resource("/").to(|| async {
+//         NamedFile::open("Cargo.toml")
+//           .unwrap()
+//           .set_content_encoding(header::ContentEncoding::Gzip)
+//       }),
+//     ))
+//     .await;
+
+//     let request = TestRequest::get()
+//       .uri("/")
+//       .header(header::ACCEPT_ENCODING, "gzip")
+//       .to_request();
+//     let res = test::call_service(&mut srv, request).await;
+//     assert_eq!(res.status(), StatusCode::OK);
+//     assert_eq!(
+//       res
+//         .headers()
+//         .get(header::CONTENT_ENCODING)
+//         .unwrap()
+//         .to_str()
+//         .unwrap(),
+//       "gzip"
+//     );
+//   }
+
+//   #[actix_rt::test]
+//   async fn test_named_file_allowed_method() {
+//     let req = TestRequest::default().method(Method::GET).to_http_request();
+//     let file = NamedFile::open("Cargo.toml").unwrap();
+//     let resp = file.respond_to(&req).await.unwrap();
+//     assert_eq!(resp.status(), StatusCode::OK);
+//   }
+
+//   #[actix_rt::test]
+//   async fn test_static_files() {
+//     let mut server_config = ServerConfig::default();
+
+//     server_config.index_strategy = Some(IndexStrategyConfig::AlwaysShowListing);
+
+//     let root_path_context = Arc::new((&server_config).try_into().unwrap());
+//     let path_contexts = Arc::new(vec![]);
+
+//     let mut srv = test::init_service(App::new().service(Files::new(
+//       "/",
+//       serve_dir("."),
+//       root_path_context,
+//       path_contexts,
+//     )))
+//     .await;
+//     let req = TestRequest::with_uri("/missing").to_request();
+
+//     let resp = test::call_service(&mut srv, req).await;
+//     assert_eq!(resp.status(), StatusCode::NOT_FOUND);
+
+//     // Without index strategy.
+//     let root_path_context = Arc::new((&ServerConfig::default()).try_into().unwrap());
+//     let path_contexts = Arc::new(vec![]);
+
+//     let mut srv = test::init_service(App::new().service(Files::new(
+//       "/",
+//       serve_dir("."),
+//       root_path_context,
+//       path_contexts,
+//     )))
+//     .await;
+
+//     let req = TestRequest::default().to_request();
+//     let resp = test::call_service(&mut srv, req).await;
+//     assert_eq!(resp.status(), StatusCode::NOT_FOUND);
+
+//     // With default renderer.
+//     server_config.index_strategy = Some(IndexStrategyConfig::AlwaysShowListing);
+
+//     let root_path_context = Arc::new((&server_config).try_into().unwrap());
+//     let path_contexts = Arc::new(vec![]);
+
+//     let mut srv = test::init_service(App::new().service(Files::new(
+//       "/",
+//       serve_dir("."),
+//       root_path_context,
+//       path_contexts,
+//     )))
+//     .await;
+//     let req = TestRequest::with_uri("/tests").to_request();
+//     let resp = test::call_service(&mut srv, req).await;
+//     assert_eq!(
+//       resp.headers().get(header::CONTENT_TYPE).unwrap(),
+//       "text/html; charset=utf-8"
+//     );
+
+//     let bytes = test::read_body(resp).await;
+//     assert!(format!("{:?}", bytes).contains("/tests/test.png"));
+//   }
+
+//   #[actix_rt::test]
+//   async fn test_redirect_to_slash_directory() {
+//     let mut server_config = ServerConfig::default();
+
+//     server_config.index_strategy = Some(IndexStrategyConfig::IndexFiles {
+//       filenames: ["test.png".to_owned()].iter().cloned().collect(),
+//     });
+
+//     let root_path_context = Arc::new((&server_config).try_into().unwrap());
+//     let path_contexts = Arc::new(vec![]);
+
+//     // should not redirect if no index
+//     // let mut srv = test::init_service(
+//     //   App::new().service(Files::new("/", serve_dir(".")).redirect_to_slash_directory()),
+//     // )
+//     // .await;
+//     // let req = TestRequest::with_uri("/tests").to_request();
+//     // let resp = test::call_service(&mut srv, req).await;
+//     // assert_eq!(resp.status(), StatusCode::NOT_FOUND);
+
+//     // should redirect if index present
+//     let mut srv = test::init_service(
+//       App::new().service(
+//         Files::new("/", serve_dir("."), root_path_context, path_contexts)
+//           .redirect_to_slash_directory(),
+//       ),
+//     )
+//     .await;
+//     let req = TestRequest::with_uri("/tests").to_request();
+//     let resp = test::call_service(&mut srv, req).await;
+//     assert_eq!(resp.status(), StatusCode::FOUND);
+
+//     // should not redirect if the path is wrong
+//     let req = TestRequest::with_uri("/not_existing").to_request();
+//     let resp = test::call_service(&mut srv, req).await;
+//     assert_eq!(resp.status(), StatusCode::NOT_FOUND);
+//   }
+
+//   #[actix_rt::test]
+//   async fn test_static_files_bad_directory() {
+//     let root_path_context = Arc::new((&ServerConfig::default()).try_into().unwrap());
+//     let path_contexts = Arc::new(vec![]);
+
+//     let _st: Files = Files::new("/", serve_dir("missing"), root_path_context, path_contexts);
+
+//     let root_path_context = Arc::new((&ServerConfig::default()).try_into().unwrap());
+//     let path_contexts = Arc::new(vec![]);
+
+//     let _st: Files = Files::new(
+//       "/",
+//       serve_dir("Cargo.toml"),
+//       root_path_context,
+//       path_contexts,
+//     );
+//   }
+
+//   #[actix_rt::test]
+//   async fn test_default_handler_file_missing() {
+//     let root_path_context = Arc::new((&ServerConfig::default()).try_into().unwrap());
+//     let path_contexts = Arc::new(vec![]);
+
+//     let mut st = Files::new("/", serve_dir("."), root_path_context, path_contexts)
+//       .default_handler(|req: ServiceRequest| {
+//         ok(req.into_response(HttpResponse::Ok().body("default content")))
+//       })
+//       .new_service(())
+//       .await
+//       .unwrap();
+//     let req = TestRequest::with_uri("/missing").to_srv_request();
+
+//     let resp = test::call_service(&mut st, req).await;
+//     assert_eq!(resp.status(), StatusCode::OK);
+//     let bytes = test::read_body(resp).await;
+//     assert_eq!(bytes, Bytes::from_static(b"default content"));
+//   }
 
   //     #[actix_rt::test]
   //     async fn test_serve_index() {
diff --git a/src/files/named.rs b/src/files/named.rs
deleted file mode 100644
index 4f9fa89..0000000
--- a/src/files/named.rs
+++ /dev/null
@@ -1,451 +0,0 @@
-use std::fs::{File, Metadata};
-use std::io;
-use std::ops::{Deref, DerefMut};
-use std::path::{Path, PathBuf};
-use std::time::{SystemTime, UNIX_EPOCH};
-
-#[cfg(unix)]
-use std::os::unix::fs::MetadataExt;
-
-use bitflags::bitflags;
-use mime_guess::from_path;
-
-use actix_http::body::SizedStream;
-use actix_web::dev::BodyEncoding;
-use actix_web::http::header::{
-  self, Charset, ContentDisposition, DispositionParam, DispositionType, ExtendedValue,
-};
-use actix_web::http::{ContentEncoding, StatusCode};
-use actix_web::{Error, HttpMessage, HttpRequest, HttpResponse, Responder};
-use futures_util::future::{ready, Ready};
-
-use super::{chunked::ChunkedReadFile, path_context::PathContext, range::HttpRange};
-
-bitflags! {
-    pub(crate) struct Flags: u8 {
-        const ETAG = 0b0000_0001;
-        const LAST_MD = 0b0000_0010;
-        const CONTENT_DISPOSITION = 0b0000_0100;
-    }
-}
-
-impl Default for Flags {
-  fn default() -> Self {
-    Flags::all()
-  }
-}
-
-/// A file with an associated name.
-#[derive(Debug)]
-pub struct NamedFile {
-  path: PathBuf,
-  file: File,
-  modified: Option<SystemTime>,
-  pub(crate) md: Metadata,
-  pub(crate) flags: Flags,
-  pub(crate) status_code: StatusCode,
-  pub(crate) content_type: mime::Mime,
-  pub(crate) content_disposition: header::ContentDisposition,
-  pub(crate) encoding: Option<ContentEncoding>,
-}
-
-impl NamedFile {
-  /// Creates an instance from a previously opened file.
-  ///
-  /// The given `path` need not exist and is only used to determine the `ContentType` and
-  /// `ContentDisposition` headers.
-  ///
-  /// # Examples
-  ///
-  /// ```rust
-  /// use espresso::files::named::NamedFile;
-  /// use std::io::{self, Write};
-  /// use std::env;
-  /// use std::fs::File;
-  ///
-  /// fn main() -> io::Result<()> {
-  ///     let mut file = File::create("foo.txt")?;
-  ///     file.write_all(b"Hello, world!")?;
-  ///     let named_file = NamedFile::from_file(file, "bar.txt")?;
-  ///     # std::fs::remove_file("foo.txt");
-  ///     Ok(())
-  /// }
-  /// ```
-  pub fn from_file<P: AsRef<Path>>(file: File, path: P) -> io::Result<NamedFile> {
-    let path = path.as_ref().to_path_buf();
-
-    // Get the name of the file and use it to construct default Content-Type
-    // and Content-Disposition values
-    let (content_type, content_disposition) = {
-      let filename = match path.file_name() {
-        Some(name) => name.to_string_lossy(),
-        None => {
-          return Err(io::Error::new(
-            io::ErrorKind::InvalidInput,
-            "Provided path has no filename",
-          ));
-        }
-      };
-
-      let ct = from_path(&path).first_or_octet_stream();
-      let disposition = match ct.type_() {
-        mime::IMAGE | mime::TEXT | mime::VIDEO => DispositionType::Inline,
-        _ => DispositionType::Attachment,
-      };
-      let mut parameters = vec![DispositionParam::Filename(String::from(filename.as_ref()))];
-      if !filename.is_ascii() {
-        parameters.push(DispositionParam::FilenameExt(ExtendedValue {
-          charset: Charset::Ext(String::from("UTF-8")),
-          language_tag: None,
-          value: filename.into_owned().into_bytes(),
-        }))
-      }
-      let cd = ContentDisposition {
-        disposition,
-        parameters,
-      };
-      (ct, cd)
-    };
-
-    let md = file.metadata()?;
-    let modified = md.modified().ok();
-    let encoding = None;
-    Ok(NamedFile {
-      path,
-      file,
-      content_type,
-      content_disposition,
-      md,
-      modified,
-      encoding,
-      status_code: StatusCode::OK,
-      flags: Flags::default(),
-    })
-  }
-
-  /// Attempts to open a file in read-only mode.
-  ///
-  /// # Examples
-  ///
-  /// ```rust
-  /// use espresso::files::named::NamedFile;
-  ///
-  /// let file = NamedFile::open("foo.txt");
-  /// ```
-  pub fn open<P: AsRef<Path>>(path: P) -> io::Result<NamedFile> {
-    Self::from_file(File::open(&path)?, path)
-  }
-
-  /// Returns reference to the underlying `File` object.
-  #[inline]
-  pub fn file(&self) -> &File {
-    &self.file
-  }
-
-  /// Retrieve the path of this file.
-  ///
-  /// # Examples
-  ///
-  /// ```rust
-  /// # use std::io;
-  /// use espresso::files::named::NamedFile;
-  ///
-  /// # fn path() -> io::Result<()> {
-  /// let file = NamedFile::open("test.txt")?;
-  /// assert_eq!(file.path().as_os_str(), "foo.txt");
-  /// # Ok(())
-  /// # }
-  /// ```
-  #[inline]
-  pub fn path(&self) -> &Path {
-    self.path.as_path()
-  }
-
-  /// Set response **Status Code**
-  pub fn set_status_code(mut self, status: StatusCode) -> Self {
-    self.status_code = status;
-    self
-  }
-
-  /// Set the MIME Content-Type for serving this file. By default
-  /// the Content-Type is inferred from the filename extension.
-  #[inline]
-  pub fn set_content_type(mut self, mime_type: mime::Mime) -> Self {
-    self.content_type = mime_type;
-    self
-  }
-
-  /// Set the Content-Disposition for serving this file. This allows
-  /// changing the inline/attachment disposition as well as the filename
-  /// sent to the peer. By default the disposition is `inline` for text,
-  /// image, and video content types, and `attachment` otherwise, and
-  /// the filename is taken from the path provided in the `open` method
-  /// after converting it to UTF-8 using.
-  /// [to_string_lossy](https://doc.rust-lang.org/std/ffi/struct.OsStr.html#method.to_string_lossy).
-  #[inline]
-  pub fn set_content_disposition(mut self, cd: header::ContentDisposition) -> Self {
-    self.content_disposition = cd;
-    self.flags.insert(Flags::CONTENT_DISPOSITION);
-    self
-  }
-
-  /// Disable `Content-Disposition` header.
-  ///
-  /// By default Content-Disposition` header is enabled.
-  #[inline]
-  pub fn disable_content_disposition(mut self) -> Self {
-    self.flags.remove(Flags::CONTENT_DISPOSITION);
-    self
-  }
-
-  /// Set content encoding for serving this file
-  #[inline]
-  pub fn set_content_encoding(mut self, enc: ContentEncoding) -> Self {
-    self.encoding = Some(enc);
-    self
-  }
-
-  #[inline]
-  ///Specifies whether to use ETag or not.
-  ///
-  ///Default is true.
-  pub fn use_etag(mut self, value: bool) -> Self {
-    self.flags.set(Flags::ETAG, value);
-    self
-  }
-
-  #[inline]
-  ///Specifies whether to use Last-Modified or not.
-  ///
-  ///Default is true.
-  pub fn use_last_modified(mut self, value: bool) -> Self {
-    self.flags.set(Flags::LAST_MD, value);
-    self
-  }
-
-  pub fn with_path_context(mut self, path_context: &PathContext) -> Self {
-    if let Some(mime_disposition) = path_context.get_mime_disposition() {
-      if let Some(new_disposition) = mime_disposition.get(&self.content_type) {
-        self.content_disposition.disposition = new_disposition.clone();
-      }
-    }
-
-    self
-      .use_etag(path_context.get_use_etag_or_default())
-      .use_last_modified(path_context.get_use_last_modifiedor_default())
-  }
-
-  pub(crate) fn etag(&self) -> Option<header::EntityTag> {
-    // This etag format is similar to Apache's.
-    self.modified.as_ref().map(|mtime| {
-      let ino = {
-        #[cfg(unix)]
-        {
-          self.md.ino()
-        }
-        #[cfg(not(unix))]
-        {
-          0
-        }
-      };
-
-      let dur = mtime
-        .duration_since(UNIX_EPOCH)
-        .expect("modification time must be after epoch");
-      header::EntityTag::strong(format!(
-        "{:x}:{:x}:{:x}:{:x}",
-        ino,
-        self.md.len(),
-        dur.as_secs(),
-        dur.subsec_nanos()
-      ))
-    })
-  }
-
-  pub(crate) fn last_modified(&self) -> Option<header::HttpDate> {
-    self.modified.map(|mtime| mtime.into())
-  }
-
-  pub fn into_response(self, req: &HttpRequest) -> Result<HttpResponse, Error> {
-    if self.status_code != StatusCode::OK {
-      let mut resp = HttpResponse::build(self.status_code);
-      resp
-        .set(header::ContentType(self.content_type.clone()))
-        .if_true(self.flags.contains(Flags::CONTENT_DISPOSITION), |res| {
-          res.header(
-            header::CONTENT_DISPOSITION,
-            self.content_disposition.to_string(),
-          );
-        });
-      if let Some(current_encoding) = self.encoding {
-        resp.encoding(current_encoding);
-      }
-      let reader = ChunkedReadFile::new(self.md.len(), 0, Some(self.file), None, 0);
-      return Ok(resp.streaming(reader));
-    }
-
-    let etag = if self.flags.contains(Flags::ETAG) {
-      self.etag()
-    } else {
-      None
-    };
-    let last_modified = if self.flags.contains(Flags::LAST_MD) {
-      self.last_modified()
-    } else {
-      None
-    };
-
-    // check preconditions
-    let precondition_failed = if !any_match(etag.as_ref(), req) {
-      true
-    } else if let (Some(ref m), Some(header::IfUnmodifiedSince(ref since))) =
-      (last_modified, req.get_header())
-    {
-      let t1: SystemTime = m.clone().into();
-      let t2: SystemTime = since.clone().into();
-      match (t1.duration_since(UNIX_EPOCH), t2.duration_since(UNIX_EPOCH)) {
-        (Ok(t1), Ok(t2)) => t1 > t2,
-        _ => false,
-      }
-    } else {
-      false
-    };
-
-    // check last modified
-    let not_modified = if !none_match(etag.as_ref(), req) {
-      true
-    } else if req.headers().contains_key(&header::IF_NONE_MATCH) {
-      false
-    } else if let (Some(ref m), Some(header::IfModifiedSince(ref since))) =
-      (last_modified, req.get_header())
-    {
-      let t1: SystemTime = m.clone().into();
-      let t2: SystemTime = since.clone().into();
-      match (t1.duration_since(UNIX_EPOCH), t2.duration_since(UNIX_EPOCH)) {
-        (Ok(t1), Ok(t2)) => t1 <= t2,
-        _ => false,
-      }
-    } else {
-      false
-    };
-
-    let mut resp = HttpResponse::build(self.status_code);
-    resp
-      .set(header::ContentType(self.content_type.clone()))
-      .if_true(self.flags.contains(Flags::CONTENT_DISPOSITION), |res| {
-        res.header(
-          header::CONTENT_DISPOSITION,
-          self.content_disposition.to_string(),
-        );
-      });
-    // default compressing
-    if let Some(current_encoding) = self.encoding {
-      resp.encoding(current_encoding);
-    }
-
-    resp
-      .if_some(last_modified, |lm, resp| {
-        resp.set(header::LastModified(lm));
-      })
-      .if_some(etag, |etag, resp| {
-        resp.set(header::ETag(etag));
-      });
-
-    resp.header(header::ACCEPT_RANGES, "bytes");
-
-    let mut length = self.md.len();
-    let mut offset = 0;
-
-    // check for range header
-    if let Some(ranges) = req.headers().get(&header::RANGE) {
-      if let Ok(rangesheader) = ranges.to_str() {
-        if let Ok(rangesvec) = HttpRange::parse(rangesheader, length) {
-          length = rangesvec[0].length;
-          offset = rangesvec[0].start;
-          resp.encoding(ContentEncoding::Identity);
-          resp.header(
-            header::CONTENT_RANGE,
-            format!("bytes {}-{}/{}", offset, offset + length - 1, self.md.len()),
-          );
-        } else {
-          resp.header(header::CONTENT_RANGE, format!("bytes */{}", length));
-          return Ok(resp.status(StatusCode::RANGE_NOT_SATISFIABLE).finish());
-        };
-      } else {
-        return Ok(resp.status(StatusCode::BAD_REQUEST).finish());
-      };
-    };
-
-    if precondition_failed {
-      return Ok(resp.status(StatusCode::PRECONDITION_FAILED).finish());
-    } else if not_modified {
-      return Ok(resp.status(StatusCode::NOT_MODIFIED).finish());
-    }
-
-    let reader = ChunkedReadFile::new(length, offset, Some(self.file), None, 0);
-
-    if offset != 0 || length != self.md.len() {
-      resp.status(StatusCode::PARTIAL_CONTENT);
-    }
-
-    Ok(resp.body(SizedStream::new(length, reader)))
-  }
-}
-
-impl Deref for NamedFile {
-  type Target = File;
-
-  fn deref(&self) -> &File {
-    &self.file
-  }
-}
-
-impl DerefMut for NamedFile {
-  fn deref_mut(&mut self) -> &mut File {
-    &mut self.file
-  }
-}
-
-impl Responder for NamedFile {
-  type Error = Error;
-  type Future = Ready<Result<HttpResponse, Error>>;
-
-  fn respond_to(self, req: &HttpRequest) -> Self::Future {
-    ready(self.into_response(req))
-  }
-}
-
-/// Returns true if `req` has no `If-Match` header or one which matches `etag`.
-fn any_match(etag: Option<&header::EntityTag>, req: &HttpRequest) -> bool {
-  match req.get_header::<header::IfMatch>() {
-    None | Some(header::IfMatch::Any) => true,
-    Some(header::IfMatch::Items(ref items)) => {
-      if let Some(some_etag) = etag {
-        for item in items {
-          if item.strong_eq(some_etag) {
-            return true;
-          }
-        }
-      }
-      false
-    }
-  }
-}
-
-/// Returns true if `req` doesn't have an `If-None-Match` header matching `req`.
-fn none_match(etag: Option<&header::EntityTag>, req: &HttpRequest) -> bool {
-  match req.get_header::<header::IfNoneMatch>() {
-    Some(header::IfNoneMatch::Any) => false,
-    Some(header::IfNoneMatch::Items(ref items)) => {
-      if let Some(some_etag) = etag {
-        for item in items {
-          if item.weak_eq(some_etag) {
-            return false;
-          }
-        }
-      }
-      true
-    }
-    None => true,
-  }
-}
diff --git a/src/files/named_ext.rs b/src/files/named_ext.rs
new file mode 100644
index 0000000..9062522
--- /dev/null
+++ b/src/files/named_ext.rs
@@ -0,0 +1,29 @@
+use actix_files::NamedFile;
+use actix_web::http::header::ContentDisposition;
+
+use super::path_context::PathContext;
+
+pub trait NamedFileExt {
+  fn with_path_context(self, path_context: &PathContext) -> Self;
+}
+
+impl NamedFileExt for NamedFile {
+  fn with_path_context(mut self, path_context: &PathContext) -> Self {
+    let mut this = self;
+
+    if let Some(mime_disposition) = path_context.get_mime_disposition() {
+      if let Some(new_disposition_type) = mime_disposition.get(&this.content_type()) {
+        let original_parameters = this.content_disposition().parameters.clone();
+
+        this = this.set_content_disposition(ContentDisposition {
+          disposition: new_disposition_type.clone(),
+          parameters: original_parameters,
+        });
+      }
+    }
+
+    this
+      .use_etag(path_context.get_use_etag_or_default())
+      .use_last_modified(path_context.get_use_last_modifiedor_default())
+  }
+}
diff --git a/src/files/path_context.rs b/src/files/path_context.rs
index 00744bd..3e22268 100644
--- a/src/files/path_context.rs
+++ b/src/files/path_context.rs
@@ -1,9 +1,6 @@
 use super::directory::index::IndexStrategy;
 use crate::config::{ContentDispositionConfig, PathConfig, PathMatcherConfig, ServerConfig};
-use actix_http::http::{
-  header::{self, DispositionType},
-  HeaderMap,
-};
+use actix_web::http::header::{DispositionType, HeaderMap, self};
 use regex::Regex;
 use snafu::{ResultExt, Snafu};
 use std::{
diff --git a/src/files/pathbuf.rs b/src/files/pathbuf.rs
index f2b119b..a336a5e 100644
--- a/src/files/pathbuf.rs
+++ b/src/files/pathbuf.rs
@@ -69,7 +69,6 @@ impl UriPathBuf {
 impl FromRequest for UriPathBuf {
   type Error = Error;
   type Future = Ready<Result<Self, Self::Error>>;
-  type Config = ();
 
   fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
     ready(req.try_into())
diff --git a/src/files/range.rs b/src/files/range.rs
deleted file mode 100644
index b4cd265..0000000
--- a/src/files/range.rs
+++ /dev/null
@@ -1,406 +0,0 @@
-use snafu::Snafu;
-
-#[derive(Snafu, Debug, PartialEq)]
-pub enum Error {
-  /// The segment started with the wrapped invalid character.
-  #[snafu(display("The range has an invalid prefix"))]
-  InvalidPrefix {
-    header: String,
-  },
-  InvalidRangeComponent,
-  InvalidRange {
-    start: i64,
-    end: i64,
-  },
-  InvalidRanges,
-}
-
-/// HTTP Range header representation.
-#[derive(Debug, Clone, Copy)]
-pub struct HttpRange {
-  /// Start of range.
-  pub start: u64,
-
-  /// Length of range.
-  pub length: u64,
-}
-
-type Result<T, E = Error> = std::result::Result<T, E>;
-
-const PREFIX: &str = "bytes=";
-const PREFIX_LEN: usize = 6;
-
-impl HttpRange {
-  /// Parses Range HTTP header string as per RFC 2616.
-  ///
-  /// `header` is HTTP Range header (e.g. `bytes=bytes=0-9`).
-  /// `size` is full size of response (file).
-  pub fn parse(header: &str, size: u64) -> Result<Vec<HttpRange>> {
-    if header.is_empty() {
-      return Ok(Vec::new());
-    } else if !header.starts_with(PREFIX) {
-      return Err(Error::InvalidPrefix {
-        header: header.to_owned(),
-      });
-    }
-
-    let size_sig = size as i64;
-    let mut no_overlap = false;
-
-    let all_ranges: Vec<Option<HttpRange>> = header[PREFIX_LEN..]
-      .split(',')
-      .map(|x| x.trim())
-      .filter(|x| !x.is_empty())
-      .map(|ra| {
-        let mut start_end_iter = ra.split('-');
-
-        let start_str = start_end_iter
-          .next()
-          .ok_or(Error::InvalidRangeComponent)?
-          .trim();
-        let end_str = start_end_iter
-          .next()
-          .ok_or(Error::InvalidRangeComponent)?
-          .trim();
-
-        if start_str.is_empty() {
-          // If no start is specified, end specifies the
-          // range start relative to the end of the file.
-          let mut length: i64 = end_str.parse().map_err(|_| Error::InvalidRangeComponent)?;
-
-          if length > size_sig {
-            length = size_sig;
-          }
-
-          Ok(Some(HttpRange {
-            start: (size_sig - length) as u64,
-            length: length as u64,
-          }))
-        } else {
-          let start: i64 = start_str
-            .parse()
-            .map_err(|_| Error::InvalidRangeComponent)?;
-
-          if start < 0 {
-            return Err(Error::InvalidRangeComponent);
-          }
-          if start >= size_sig {
-            no_overlap = true;
-            return Ok(None);
-          }
-
-          let length = if end_str.is_empty() {
-            // If no end is specified, range extends to end of the file.
-            size_sig - start
-          } else {
-            let mut end: i64 = end_str.parse().map_err(|_| Error::InvalidRangeComponent)?;
-
-            if start > end {
-              return Err(Error::InvalidRange { start, end });
-            }
-
-            if end >= size_sig {
-              end = size_sig - 1;
-            }
-
-            end - start + 1
-          };
-
-          Ok(Some(HttpRange {
-            start: start as u64,
-            length: length as u64,
-          }))
-        }
-      })
-      .collect::<Result<Vec<Option<HttpRange>>, Error>>()?;
-
-    let ranges: Vec<HttpRange> = all_ranges.into_iter().filter_map(|x| x).collect();
-
-    if no_overlap && ranges.is_empty() {
-      return Err(Error::InvalidRanges);
-    }
-
-    Ok(ranges)
-  }
-}
-
-#[cfg(test)]
-mod tests {
-  use super::*;
-
-  struct T(&'static str, u64, Vec<HttpRange>);
-
-  #[test]
-  fn test_parse() {
-    let tests = vec![
-      T("", 0, vec![]),
-      T("", 1000, vec![]),
-      T("foo", 0, vec![]),
-      T("bytes=", 0, vec![]),
-      T("bytes=7", 10, vec![]),
-      T("bytes= 7 ", 10, vec![]),
-      T("bytes=1-", 0, vec![]),
-      T("bytes=5-4", 10, vec![]),
-      T("bytes=0-2,5-4", 10, vec![]),
-      T("bytes=2-5,4-3", 10, vec![]),
-      T("bytes=--5,4--3", 10, vec![]),
-      T("bytes=A-", 10, vec![]),
-      T("bytes=A- ", 10, vec![]),
-      T("bytes=A-Z", 10, vec![]),
-      T("bytes= -Z", 10, vec![]),
-      T("bytes=5-Z", 10, vec![]),
-      T("bytes=Ran-dom, garbage", 10, vec![]),
-      T("bytes=0x01-0x02", 10, vec![]),
-      T("bytes=         ", 10, vec![]),
-      T("bytes= , , ,   ", 10, vec![]),
-      T(
-        "bytes=0-9",
-        10,
-        vec![HttpRange {
-          start: 0,
-          length: 10,
-        }],
-      ),
-      T(
-        "bytes=0-",
-        10,
-        vec![HttpRange {
-          start: 0,
-          length: 10,
-        }],
-      ),
-      T(
-        "bytes=5-",
-        10,
-        vec![HttpRange {
-          start: 5,
-          length: 5,
-        }],
-      ),
-      T(
-        "bytes=0-20",
-        10,
-        vec![HttpRange {
-          start: 0,
-          length: 10,
-        }],
-      ),
-      T(
-        "bytes=15-,0-5",
-        10,
-        vec![HttpRange {
-          start: 0,
-          length: 6,
-        }],
-      ),
-      T(
-        "bytes=1-2,5-",
-        10,
-        vec![
-          HttpRange {
-            start: 1,
-            length: 2,
-          },
-          HttpRange {
-            start: 5,
-            length: 5,
-          },
-        ],
-      ),
-      T(
-        "bytes=-2 , 7-",
-        11,
-        vec![
-          HttpRange {
-            start: 9,
-            length: 2,
-          },
-          HttpRange {
-            start: 7,
-            length: 4,
-          },
-        ],
-      ),
-      T(
-        "bytes=0-0 ,2-2, 7-",
-        11,
-        vec![
-          HttpRange {
-            start: 0,
-            length: 1,
-          },
-          HttpRange {
-            start: 2,
-            length: 1,
-          },
-          HttpRange {
-            start: 7,
-            length: 4,
-          },
-        ],
-      ),
-      T(
-        "bytes=-5",
-        10,
-        vec![HttpRange {
-          start: 5,
-          length: 5,
-        }],
-      ),
-      T(
-        "bytes=-15",
-        10,
-        vec![HttpRange {
-          start: 0,
-          length: 10,
-        }],
-      ),
-      T(
-        "bytes=0-499",
-        10000,
-        vec![HttpRange {
-          start: 0,
-          length: 500,
-        }],
-      ),
-      T(
-        "bytes=500-999",
-        10000,
-        vec![HttpRange {
-          start: 500,
-          length: 500,
-        }],
-      ),
-      T(
-        "bytes=-500",
-        10000,
-        vec![HttpRange {
-          start: 9500,
-          length: 500,
-        }],
-      ),
-      T(
-        "bytes=9500-",
-        10000,
-        vec![HttpRange {
-          start: 9500,
-          length: 500,
-        }],
-      ),
-      T(
-        "bytes=0-0,-1",
-        10000,
-        vec![
-          HttpRange {
-            start: 0,
-            length: 1,
-          },
-          HttpRange {
-            start: 9999,
-            length: 1,
-          },
-        ],
-      ),
-      T(
-        "bytes=500-600,601-999",
-        10000,
-        vec![
-          HttpRange {
-            start: 500,
-            length: 101,
-          },
-          HttpRange {
-            start: 601,
-            length: 399,
-          },
-        ],
-      ),
-      T(
-        "bytes=500-700,601-999",
-        10000,
-        vec![
-          HttpRange {
-            start: 500,
-            length: 201,
-          },
-          HttpRange {
-            start: 601,
-            length: 399,
-          },
-        ],
-      ),
-      // Match Apache laxity:
-      T(
-        "bytes=   1 -2   ,  4- 5, 7 - 8 , ,,",
-        11,
-        vec![
-          HttpRange {
-            start: 1,
-            length: 2,
-          },
-          HttpRange {
-            start: 4,
-            length: 2,
-          },
-          HttpRange {
-            start: 7,
-            length: 2,
-          },
-        ],
-      ),
-    ];
-
-    for t in tests {
-      let header = t.0;
-      let size = t.1;
-      let expected = t.2;
-
-      let res = HttpRange::parse(header, size);
-
-      if res.is_err() {
-        if expected.is_empty() {
-          continue;
-        } else {
-          assert!(
-            false,
-            "parse({}, {}) returned error {:?}",
-            header,
-            size,
-            res.unwrap_err()
-          );
-        }
-      }
-
-      let got = res.unwrap();
-
-      if got.len() != expected.len() {
-        assert!(
-          false,
-          "len(parseRange({}, {})) = {}, want {}",
-          header,
-          size,
-          got.len(),
-          expected.len()
-        );
-        continue;
-      }
-
-      for i in 0..expected.len() {
-        if got[i].start != expected[i].start {
-          assert!(
-            false,
-            "parseRange({}, {})[{}].start = {}, want {}",
-            header, size, i, got[i].start, expected[i].start
-          )
-        }
-        if got[i].length != expected[i].length {
-          assert!(
-            false,
-            "parseRange({}, {})[{}].length = {}, want {}",
-            header, size, i, got[i].length, expected[i].length
-          )
-        }
-      }
-    }
-  }
-}
diff --git a/src/files/service.rs b/src/files/service.rs
index 263e849..afab4c1 100644
--- a/src/files/service.rs
+++ b/src/files/service.rs
@@ -1,19 +1,22 @@
 use super::{
   directory::{index::IndexStrategy, Directory},
-  named::NamedFile,
+  named_ext::NamedFileExt,
   pages::render_server_page,
   path::resolve_path_within_tree,
   path_context::PathContext,
   pathbuf::UriPathBuf,
 };
-use actix_service::{boxed::BoxService, Service};
+use actix_files::NamedFile;
+use actix_service::boxed::BoxService;
 use actix_web::{
-  dev::{ServiceRequest, ServiceResponse},
+  body::BoxBody,
+  dev::{Service, ServiceRequest, ServiceResponse},
   error::Error as ActixError,
   guard::Guard,
   http::{header, Method, StatusCode},
   HttpResponse, ResponseError,
 };
+use async_recursion::async_recursion;
 use futures_util::future::{err, ok, Either, LocalBoxFuture, Ready};
 use snafu::ResultExt;
 use snafu::Snafu;
@@ -24,6 +27,7 @@ use std::{
   rc::Rc,
   sync::{Arc, RwLock},
   task::{Context, Poll},
+  ops::Deref,
 };
 
 /// Errors which can occur when serving static files.
@@ -78,7 +82,7 @@ impl ResponseError for Error {
   fn error_response(&self) -> HttpResponse {
     match self {
       Error::MethodNotAllowed { .. } => HttpResponse::MethodNotAllowed()
-        .header(header::CONTENT_TYPE, "text/plain")
+        .append_header((header::CONTENT_TYPE, "text/plain"))
         .body("Request did not meet this resource's requirements."),
       _ => HttpResponse::new(StatusCode::NOT_FOUND),
     }
@@ -93,20 +97,27 @@ struct RequestContext {
   path_context: PathContext,
 }
 
-pub struct FilesService {
+#[derive(Clone)]
+pub struct FilesService(pub(crate) Rc<FilesServiceInner>);
+
+impl Deref for FilesService {
+    type Target = FilesServiceInner;
+
+    fn deref(&self) -> &Self::Target {
+        &self.0
+    }
+}
+
+pub struct FilesServiceInner {
   directory: Arc<RwLock<Option<PathBuf>>>,
   redirect_to_slash: bool,
-  default: Option<HttpService>,
+  pub(crate) default: Option<HttpService>,
   root_path_context: Arc<PathContext>,
-  #[allow(clippy::rc_buffer)]
   path_contexts: Arc<Vec<PathContext>>,
-  // FIXME: Should re-visit later.
-  #[allow(clippy::redundant_allocation)]
   guards: Option<Rc<dyn Guard>>,
 }
 
-impl FilesService {
-  #[allow(clippy::rc_buffer)]
+impl FilesServiceInner {
   pub(crate) fn new(
     directory: Arc<RwLock<Option<PathBuf>>>,
     redirect_to_slash: bool,
@@ -114,8 +125,8 @@ impl FilesService {
     root_path_context: Arc<PathContext>,
     path_contexts: Arc<Vec<PathContext>>,
     guards: Option<Rc<dyn Guard>>,
-  ) -> FilesService {
-    FilesService {
+  ) -> FilesServiceInner {
+    FilesServiceInner {
       directory,
       redirect_to_slash,
       default,
@@ -129,61 +140,55 @@ impl FilesService {
     self.default = default
   }
 
-  fn handle_err(
-    &mut self,
+  #[async_recursion(?Send)]
+  async fn handle_err(
+    &self,
     e: Error,
     req: ServiceRequest,
     request_context: Option<RequestContext>,
-  ) -> Either<
-    Ready<Result<ServiceResponse, ActixError>>,
-    LocalBoxFuture<'static, Result<ServiceResponse, ActixError>>,
-  > {
+  ) -> Result<ServiceResponse, ActixError> {
     log::debug!("Files: Failed to handle {}: {}", req.path(), e);
 
-    if let Some(ref mut default) = self.default {
+    if let Some(ref default) = self.default {
       info!("Using default handler");
 
-      Either::Right(default.call(req))
+      default.call(req).await
     } else {
       let error_response = e.error_response();
 
       match error_response.status() {
-        StatusCode::NOT_FOUND => self.handle_not_found_err(req, request_context),
-        _ => Either::Left(ok(req.into_response(error_response))),
+        StatusCode::NOT_FOUND => self.handle_not_found_err(req, request_context).await,
+        _ => Ok(req.into_response(error_response)),
       }
     }
   }
 
-  fn handle_early_err(
-    &mut self,
+  fn get_request_context_for_request(&self, req: &ServiceRequest) -> Result<RequestContext, Error> {
+    let serve_dir = self.get_serve_dir()?;
+    let path_from_request: UriPathBuf = req.try_into().context(BuildUriPath)?;
+
+    Ok(RequestContext {
+      path: serve_dir.join(&path_from_request),
+      serve_dir,
+      path_context: self.get_path_context(&path_from_request),
+    })
+  }
+
+  async fn handle_early_err(
+    &self,
     e: Error,
     req: ServiceRequest,
-  ) -> Either<
-    Ready<Result<ServiceResponse, ActixError>>,
-    LocalBoxFuture<'static, Result<ServiceResponse, ActixError>>,
-  > {
-    let request_context: Result<RequestContext, Error> = try {
-      let serve_dir = self.get_serve_dir()?;
-      let path_from_request: UriPathBuf = (&req).try_into().context(BuildUriPath)?;
-
-      RequestContext {
-        path: serve_dir.join(&path_from_request),
-        serve_dir,
-        path_context: self.get_path_context(&path_from_request),
-      }
-    };
+  ) -> Result<ServiceResponse, ActixError> {
+    let request_context = self.get_request_context_for_request(&req);
 
-    self.handle_err(e, req, request_context.ok())
+    self.handle_err(e, req, request_context.ok()).await
   }
 
-  fn handle_not_found_err(
-    &mut self,
+  async fn handle_not_found_err(
+    &self,
     req: ServiceRequest,
     request_context: Option<RequestContext>,
-  ) -> Either<
-    Ready<Result<ServiceResponse, ActixError>>,
-    LocalBoxFuture<'static, Result<ServiceResponse, ActixError>>,
-  > {
+  ) -> Result<ServiceResponse, ActixError> {
     if let Some(request_context) = request_context {
       debug!(
         "Using custom error path: {:?}",
@@ -200,14 +205,16 @@ impl FilesService {
           Ok(path) => {
             debug!("Custom error page: {:?}", path);
 
-            return self.handle_file(
-              req,
-              RequestContext {
-                path,
-                ..request_context
-              },
-              false,
-            );
+            return self
+              .handle_file(
+                req,
+                RequestContext {
+                  path,
+                  ..request_context
+                },
+                false,
+              )
+              .await;
           }
           Err(err) => error!("Error resolving custom error page: {}", err),
         }
@@ -215,38 +222,38 @@ impl FilesService {
     }
 
     match render_server_page("404", "Not Found", "") {
-      Ok(body) => Either::Left(ok(
+      Ok(body) => Ok(
         req.into_response(
           HttpResponse::NotFound()
             .content_type("text/html; charset=utf-8")
-            .body(&body),
+            .body(body),
         ),
-      )),
-      Err(_) => self.handle_err(Error::ServeCustomNotFoundPath, req, None),
+      ),
+      Err(_) => {
+        self
+          .handle_err(Error::ServeCustomNotFoundPath, req, None)
+          .await
+      }
     }
   }
 
-  fn handle_dir(
-    &mut self,
+  async fn handle_dir(
+    &self,
     req: ServiceRequest,
     request_context: RequestContext,
-  ) -> Either<
-    Ready<Result<ServiceResponse, ActixError>>,
-    LocalBoxFuture<'static, Result<ServiceResponse, ActixError>>,
-  > {
+  ) -> Result<ServiceResponse, ActixError> {
     // Check if we should redirect the client to a normalized path ending in a
     // slash.
     if self.redirect_to_slash && !req.path().ends_with('/') {
       let redirect_to = format!("{}/", req.path());
 
-      return Either::Left(ok(
+      return Ok(
         req.into_response(
           HttpResponse::Found()
-            .header(header::LOCATION, redirect_to)
-            .body("")
-            .into_body(),
+            .append_header((header::LOCATION, redirect_to))
+            .body(""),
         ),
-      ));
+      );
     }
 
     let RequestContext {
@@ -261,11 +268,14 @@ impl FilesService {
         let (http_req, payload) = req.into_parts();
 
         match renderer(&dir, &http_req) {
-          Ok(resp) => Either::Left(ok(resp)),
-          Err(source) => match ServiceRequest::from_parts(http_req, payload) {
-            Ok(req) => self.handle_err(Error::RenderListing { source }, req, Some(request_context)),
-            Err(_) => Either::Left(err(Error::ReconstructRequest.into())),
-          },
+          Ok(resp) => Ok(resp),
+          Err(source) => {
+            let req = ServiceRequest::from_parts(http_req, payload);
+
+            self
+              .handle_err(Error::RenderListing { source }, req, Some(request_context))
+              .await
+          }
         }
       }
       IndexStrategy::ShowListingWhenAbsent {
@@ -276,15 +286,17 @@ impl FilesService {
           let path = path.join(filename);
 
           if path.exists() {
-            return self.handle_file(
-              req,
-              RequestContext {
-                serve_dir: request_context.serve_dir,
-                path,
-                path_context: request_context.path_context,
-              },
-              true,
-            );
+            return self
+              .handle_file(
+                req,
+                RequestContext {
+                  serve_dir: request_context.serve_dir,
+                  path,
+                  path_context: request_context.path_context,
+                },
+                true,
+              )
+              .await;
           }
         }
 
@@ -292,11 +304,14 @@ impl FilesService {
         let (http_req, payload) = req.into_parts();
 
         match renderer(&dir, &http_req) {
-          Ok(resp) => Either::Left(ok(resp)),
-          Err(source) => match ServiceRequest::from_parts(http_req, payload) {
-            Ok(req) => self.handle_err(Error::RenderListing { source }, req, Some(request_context)),
-            Err(_) => Either::Left(err(Error::ReconstructRequest.into())),
-          },
+          Ok(resp) => Ok(resp),
+          Err(source) => {
+            let req = ServiceRequest::from_parts(http_req, payload);
+
+            self
+              .handle_err(Error::RenderListing { source }, req, Some(request_context))
+              .await
+          }
         }
       }
       IndexStrategy::IndexFiles { filenames } => {
@@ -304,32 +319,37 @@ impl FilesService {
           let path = path.join(filename);
 
           if path.exists() {
-            return self.handle_file(
-              req,
-              RequestContext {
-                path,
-                ..request_context
-              },
-              true,
-            );
+            return self
+              .handle_file(
+                req,
+                RequestContext {
+                  path,
+                  ..request_context
+                },
+                true,
+              )
+              .await;
           }
         }
 
-        self.handle_err(Error::IsDirectory, req, Some(request_context))
+        self
+          .handle_err(Error::IsDirectory, req, Some(request_context))
+          .await
+      }
+      IndexStrategy::NoIndex => {
+        self
+          .handle_err(Error::IsDirectory, req, Some(request_context))
+          .await
       }
-      IndexStrategy::NoIndex => self.handle_err(Error::IsDirectory, req, Some(request_context)),
     };
   }
 
-  fn handle_file(
-    &mut self,
+  async fn handle_file(
+    &self,
     req: ServiceRequest,
     request_context: RequestContext,
     preserve_request_context: bool,
-  ) -> Either<
-    Ready<Result<ServiceResponse, ActixError>>,
-    LocalBoxFuture<'static, Result<ServiceResponse, ActixError>>,
-  > {
+  ) -> Result<ServiceResponse, ActixError> {
     let RequestContext {
       path, path_context, ..
     } = &request_context;
@@ -338,38 +358,27 @@ impl FilesService {
       Ok(named_file) => {
         let (http_req, payload) = req.into_parts();
 
-        match named_file
+        let mut response = named_file
           .with_path_context(&path_context)
-          .into_response(&http_req)
-        {
-          Ok(mut response) => {
-            path_context.append_headers_to_map(response.headers_mut());
+          .into_response(&http_req);
 
-            Either::Left(ok(ServiceResponse::new(http_req, response)))
-          }
-          Err(source) => match ServiceRequest::from_parts(http_req, payload) {
-            Ok(req) => self.handle_err(
-              Error::BuildFileResponse { source },
-              req,
-              if preserve_request_context {
-                Some(request_context)
-              } else {
-                None
-              },
-            ),
-            Err(_) => Either::Left(err(Error::ReconstructRequest.into())),
-          },
-        }
+        path_context.append_headers_to_map(response.headers_mut());
+
+        Ok(ServiceResponse::new(http_req, response))
+      }
+      Err(e) => {
+        self
+          .handle_err(
+            e,
+            req,
+            if preserve_request_context {
+              Some(request_context)
+            } else {
+              None
+            },
+          )
+          .await
       }
-      Err(e) => self.handle_err(
-        e,
-        req,
-        if preserve_request_context {
-          Some(request_context)
-        } else {
-          None
-        },
-      ),
     }
   }
 
@@ -424,54 +433,55 @@ impl FilesService {
   }
 }
 
-impl Service for FilesService {
-  type Request = ServiceRequest;
-  type Response = ServiceResponse;
+impl Service<ServiceRequest> for FilesService {
+  type Response = ServiceResponse<BoxBody>;
   type Error = ActixError;
-  type Future = Either<
-    Ready<Result<Self::Response, Self::Error>>,
-    LocalBoxFuture<'static, Result<Self::Response, Self::Error>>,
-  >;
+  type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;
 
-  fn poll_ready(&mut self, _: &mut Context) -> Poll<Result<(), Self::Error>> {
+  fn poll_ready(&self, _: &mut Context) -> Poll<Result<(), Self::Error>> {
     Poll::Ready(Ok(()))
   }
 
-  fn call(&mut self, req: ServiceRequest) -> Self::Future {
-    // Check user-defined guards or fallback to default method check.
+  fn call(&self, req: ServiceRequest) -> Self::Future {
     let is_method_valid = if let Some(guard) = &self.guards {
-      (**guard).check(req.head())
+      (**guard).check(&req.guard_ctx())
     } else {
       matches!(*req.method(), Method::HEAD | Method::GET)
     };
 
-    if !is_method_valid {
-      return self.handle_early_err(
-        Error::MethodNotAllowed {
-          method: req.method().clone(),
-        },
-        req,
-      );
-    }
+    let this = self.clone();
+
+    Box::pin(async move {
+      if !is_method_valid {
+        return this
+          .handle_early_err(
+            Error::MethodNotAllowed {
+              method: req.method().clone(),
+            },
+            req,
+          )
+          .await;
+      }
 
-    let maybe_path = self.get_canonical_path_from_request(&req);
-    let (path, serve_dir, path_from_request) = match maybe_path {
-      Ok(path) => path,
-      Err(e) => return self.handle_early_err(e, req),
-    };
+      let maybe_path = this.get_canonical_path_from_request(&req);
+      let (path, serve_dir, path_from_request) = match maybe_path {
+        Ok(path) => path,
+        Err(e) => return this.handle_early_err(e, req).await,
+      };
 
-    let path_context = self.get_path_context(&path_from_request);
+      let path_context = this.get_path_context(&path_from_request);
 
-    let request_context = RequestContext {
-      path,
-      serve_dir,
-      path_context,
-    };
+      let request_context = RequestContext {
+        path,
+        serve_dir,
+        path_context,
+      };
 
-    if request_context.path.is_dir() {
-      self.handle_dir(req, request_context)
-    } else {
-      self.handle_file(req, request_context, true)
-    }
+      if request_context.path.is_dir() {
+        this.handle_dir(req, request_context).await
+      } else {
+        this.handle_file(req, request_context, true).await
+      }
+    })
   }
 }
diff --git a/src/main.rs b/src/main.rs
index 4c00275..effc2b3 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -4,8 +4,8 @@
 extern crate log;
 
 use actix::prelude::*;
-use clap::Clap;
-use collective::cli::{AppOpts, ConfigurableAppOpts};
+use clap::{Parser, Subcommand};
+use collective::{cli::{AppOpts, ConfigurableAppOpts}, config::ConfigFileFormat};
 use lazy_static::lazy_static;
 use monitor::Monitor;
 use server::Server;
@@ -59,7 +59,7 @@ pub enum Error {
 
 type Result<T, E = Error> = std::result::Result<T, E>;
 
-#[derive(Clap)]
+#[derive(Parser)]
 #[clap(version = "1.0", author = "Eduardo T. <ed@trujillo.io>")]
 struct Opts {
   /// Sets a custom config file.
@@ -72,7 +72,7 @@ struct Opts {
   subcmd: SubCommand,
 }
 
-#[derive(Clap)]
+#[derive(Subcommand)]
 enum SubCommand {
   /// Start the server
   Serve,
@@ -80,7 +80,7 @@ enum SubCommand {
 }
 
 /// Create a bundle using the configured bundler
-#[derive(Clap)]
+#[derive(Parser)]
 struct BundleOpts {
   /// The path to use a source for the bundle.
   source_path: PathBuf,
@@ -98,9 +98,9 @@ impl AppOpts for Opts {
 }
 
 impl ConfigurableAppOpts<config::Config> for Opts {
-  fn get_additional_config_paths(&self) -> Vec<PathBuf> {
+  fn get_additional_config_paths(&self) -> Vec<(PathBuf, Option<ConfigFileFormat>)> {
     if let Some(config_path) = &self.config {
-      vec![config_path.clone()]
+      vec![(config_path.clone(), None)]
     } else {
       vec![]
     }
@@ -143,6 +143,8 @@ async fn bundle(config: Arc<config::Config>, opts: BundleOpts) -> Result<()> {
 }
 
 async fn serve(config: Arc<config::Config>) -> Result<()> {
+  console_subscriber::init();
+
   // Set up a channel for receiving thread notifications.
   let (monitor_tx, monitor_rx) = mpsc::channel();
 
@@ -188,7 +190,7 @@ async fn serve(config: Arc<config::Config>) -> Result<()> {
 
   let (unbundler_join_handle, unbundler_thread_handle) =
     thread::spawn(monitor_tx.clone(), move || {
-      let mut sys = System::new("unbundler");
+      let mut sys = System::new();
 
       let result = sys
         .block_on(async move { unbundler.enter().await })
diff --git a/src/server.rs b/src/server.rs
index 880940c..8425eb4 100644
--- a/src/server.rs
+++ b/src/server.rs
@@ -6,8 +6,9 @@ use crate::{
 };
 use actix::System;
 use actix_http::http::{uri::InvalidUri, ContentEncoding};
+use actix_rt::Runtime;
 use actix_web::{
-  dev::Server as ActixServer,
+  dev::{Server as ActixServer, ServerHandle},
   middleware::{self, Logger},
   App, HttpServer,
 };
@@ -59,7 +60,9 @@ impl Server {
   pub async fn spawn(
     self,
     notify_sender: Sender<Thread>,
-  ) -> Result<(ActixServer, JoinHandle<Result<()>>, ThreadHandle)> {
+  ) -> Result<(ServerHandle, JoinHandle<Result<()>>, ThreadHandle)> {
+    log::debug!("Starting server thread");
+
     let (tx, rx) = mpsc::channel();
 
     let server_address = self.config.address;
@@ -80,7 +83,7 @@ impl Server {
     let path_contexts = Arc::new(path_contexts);
 
     let (join_handle, thread_handle) = thread::spawn(notify_sender, move || {
-      let sys = System::new("http-server");
+      let rt = Runtime::new().unwrap();
 
       let srv = HttpServer::new(move || {
         let mut files_service = Files::new(
@@ -96,17 +99,7 @@ impl Server {
 
         App::new()
           .wrap(Logger::default())
-          .wrap(middleware::Compress::new(match &compression {
-            Some(compression) => match compression {
-              CompressionConfig::Auto => ContentEncoding::Auto,
-              CompressionConfig::Brotli => ContentEncoding::Br,
-              CompressionConfig::Disabled => ContentEncoding::Identity,
-              CompressionConfig::Deflate => ContentEncoding::Deflate,
-              CompressionConfig::Gzip => ContentEncoding::Gzip,
-            },
-            // Default to auto if not specified in the config.
-            _ => ContentEncoding::Auto,
-          }))
+          .wrap(middleware::Compress::default())
           .default_service(files_service)
       })
       .bind(server_address)
@@ -114,11 +107,21 @@ impl Server {
       .shutdown_timeout(60)
       .run();
 
-      let _ = tx.send(srv);
+      let _ = tx.send(srv.handle());
+
+      rt.block_on(async {
+        srv.await
+      });
+
+      Ok(())
 
-      sys.run().context(SystemRun)
+      //log::debug!("Starting server event loop");
+
+      //sys.run().context(SystemRun)
     });
 
+    log::debug!("!!!!!!!!!!!!!!!!!!!!!!!!!!!");
+
     Ok((
       rx.recv().context(ChannelReceive)?,
       join_handle,
diff --git a/src/stats.rs b/src/stats.rs
index d3c736f..cd047a6 100644
--- a/src/stats.rs
+++ b/src/stats.rs
@@ -3,8 +3,9 @@ use crate::{
   bundle::{Unbundler, UnbundlerStatus},
   config::StatsConfig,
 };
-use actix::System;
-use actix_web::{dev::Server, middleware::Logger, App, HttpResponse, HttpServer, Responder};
+use actix_rt::Runtime;
+use actix_web::dev::ServerHandle;
+use actix_web::{middleware::Logger, App, HttpResponse, HttpServer, Responder};
 use mpsc::{RecvError, SendError, Sender};
 use serde::Serialize;
 use snafu::{ResultExt, Snafu};
@@ -16,7 +17,7 @@ use std::{
 
 #[derive(Debug, Snafu)]
 pub enum Error {
-  ChannelSend { source: SendError<Server> },
+  ChannelSend { source: SendError<ServerHandle> },
   ChannelReceive { source: RecvError },
   Bind { source: std::io::Error },
   SystemRun { source: std::io::Error },
@@ -41,11 +42,11 @@ impl StatsServer {
   pub async fn spawn(
     self,
     notify_sender: Sender<Thread>,
-  ) -> Result<(Server, JoinHandle<Result<()>>, ThreadHandle)> {
+  ) -> Result<(ServerHandle, JoinHandle<Result<()>>, ThreadHandle)> {
     let (tx, rx) = mpsc::channel();
 
     let (join_handle, thread_handle) = thread::spawn(notify_sender, move || {
-      let sys = System::new("stats-http-server");
+      let rt = Runtime::new().unwrap();
 
       let unbundler = self.unbundler.clone();
       let server_address = self.config.address;
@@ -64,9 +65,13 @@ impl StatsServer {
       .shutdown_timeout(60)
       .run();
 
-      tx.send(srv).context(ChannelSend)?;
+      tx.send(srv.handle()).context(ChannelSend)?;
 
-      sys.run().context(SystemRun)
+      rt.block_on(async {
+        srv.await
+      });
+
+      Ok(())
     });
 
     Ok((
@@ -83,14 +88,16 @@ struct GetStatusResponse {
   serve_dir: Option<PathBuf>,
 }
 
-async fn get_status(data: actix_web::web::Data<State>) -> impl Responder {
-  let result: anyhow::Result<String> = try {
-    let status = data.unbundler.get_status()?;
+async fn try_get_status(data: actix_web::web::Data<State>) -> anyhow::Result<String> {
+  let status = data.unbundler.get_status()?;
     let serve_dir = data.unbundler.get_serve_dir()?;
 
-    serde_json::to_string(&GetStatusResponse { status, serve_dir })?
-  };
+  Ok(serde_json::to_string(&GetStatusResponse { status, serve_dir })?)
+}
 
+async fn get_status(data: actix_web::web::Data<State>) -> impl Responder {
+  let result = try_get_status(data).await;
+  
   match result {
     Ok(response) => HttpResponse::Ok().body(response),
     Err(_) => HttpResponse::InternalServerError().body("Internal Server Error"),
-- 
GitLab