diff --git a/Cargo.lock b/Cargo.lock
index 3124e0626ad7380fa14687c3a299ab58ca8a2a11..e9ee7a4fe02b84b3de148415bf6c41287fa625e4 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -8,22 +8,68 @@ version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
 
+[[package]]
+name = "aead"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0"
+dependencies = [
+ "crypto-common",
+ "generic-array",
+]
+
+[[package]]
+name = "aes"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2"
+dependencies = [
+ "cfg-if",
+ "cipher",
+ "cpufeatures",
+]
+
+[[package]]
+name = "aes-gcm"
+version = "0.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "209b47e8954a928e1d72e86eca7000ebb6655fe1436d33eefc2201cad027e237"
+dependencies = [
+ "aead",
+ "aes",
+ "cipher",
+ "ctr",
+ "ghash",
+ "subtle",
+]
+
 [[package]]
 name = "ahash"
 version = "0.7.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
 dependencies = [
- "getrandom 0.2.8",
+ "getrandom 0.2.10",
+ "once_cell",
+ "version_check",
+]
+
+[[package]]
+name = "ahash"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f"
+dependencies = [
+ "cfg-if",
  "once_cell",
  "version_check",
 ]
 
 [[package]]
 name = "aho-corasick"
-version = "0.7.20"
+version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
+checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41"
 dependencies = [
  "memchr",
 ]
@@ -43,6 +89,18 @@ dependencies = [
  "alloc-no-stdlib",
 ]
 
+[[package]]
+name = "allocator-api2"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56fc6cf8dc8c4158eed8649f9b8b0ea1518eb62b544fe9490d66fa0b349eafe9"
+
+[[package]]
+name = "android-tzdata"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
+
 [[package]]
 name = "android_system_properties"
 version = "0.1.5"
@@ -54,33 +112,19 @@ dependencies = [
 
 [[package]]
 name = "arrayvec"
-version = "0.7.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6"
-
-[[package]]
-name = "async-compression"
-version = "0.3.15"
+version = "0.7.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "942c7cd7ae39e91bde4820d74132e9862e62c2f386c3aa90ccf55949f5bad63a"
-dependencies = [
- "brotli",
- "flate2",
- "futures-core",
- "memchr",
- "pin-project-lite",
- "tokio",
-]
+checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711"
 
 [[package]]
 name = "async-trait"
-version = "0.1.59"
+version = "0.1.68"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "31e6e93155431f3931513b243d371981bb2770112b370c82745a1d19d2f99364"
+checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 2.0.22",
 ]
 
 [[package]]
@@ -92,6 +136,12 @@ dependencies = [
  "num-traits",
 ]
 
+[[package]]
+name = "atomic"
+version = "0.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c59bdb34bc650a32731b31bd8f0829cc15d24a708ee31559e0bb34f2bc320cba"
+
 [[package]]
 name = "autocfg"
 version = "1.1.0"
@@ -108,7 +158,7 @@ dependencies = [
  "proc-macro-error",
  "proc-macro2",
  "quote",
- "syn",
+ "syn 1.0.109",
 ]
 
 [[package]]
@@ -123,6 +173,12 @@ version = "0.13.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
 
+[[package]]
+name = "base64"
+version = "0.21.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d"
+
 [[package]]
 name = "beef"
 version = "0.5.2"
@@ -137,9 +193,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
 
 [[package]]
 name = "block-buffer"
-version = "0.10.3"
+version = "0.10.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e"
+checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
 dependencies = [
  "generic-array",
 ]
@@ -157,9 +213,9 @@ dependencies = [
 
 [[package]]
 name = "brotli-decompressor"
-version = "2.3.2"
+version = "2.3.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "59ad2d4653bf5ca36ae797b1f4bb4dbddb60ce49ca4aed8a2ce4829f60425b80"
+checksum = "4b6561fd3f895a11e8f72af2cb7d22e08366bebc2b6b57f7744c4bda27034744"
 dependencies = [
  "alloc-no-stdlib",
  "alloc-stdlib",
@@ -167,15 +223,9 @@ dependencies = [
 
 [[package]]
 name = "bumpalo"
-version = "3.11.1"
+version = "3.13.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba"
-
-[[package]]
-name = "bytecount"
-version = "0.6.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2c676a478f63e9fa2dd5368a42f28bba0d6c560b775f38583c8bbaa7fcd67c9c"
+checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1"
 
 [[package]]
 name = "byteorder"
@@ -185,15 +235,18 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
 
 [[package]]
 name = "bytes"
-version = "1.3.0"
+version = "1.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c"
+checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be"
 
 [[package]]
 name = "cc"
-version = "1.0.77"
+version = "1.0.79"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4"
+checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
+dependencies = [
+ "jobserver",
+]
 
 [[package]]
 name = "cfg-if"
@@ -203,13 +256,13 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 
 [[package]]
 name = "chrono"
-version = "0.4.23"
+version = "0.4.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f"
+checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5"
 dependencies = [
+ "android-tzdata",
  "iana-time-zone",
  "js-sys",
- "num-integer",
  "num-traits",
  "time 0.1.45",
  "wasm-bindgen",
@@ -226,84 +279,61 @@ dependencies = [
 ]
 
 [[package]]
-name = "codespan-reporting"
-version = "0.11.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e"
-dependencies = [
- "termcolor",
- "unicode-width",
-]
-
-[[package]]
-name = "config"
-version = "0.13.3"
+name = "cipher"
+version = "0.4.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d379af7f68bfc21714c6c7dea883544201741d2ce8274bb12fa54f89507f52a7"
+checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
 dependencies = [
- "async-trait",
- "json5",
- "lazy_static",
- "nom",
- "pathdiff",
- "ron",
- "rust-ini",
- "serde",
- "serde_json",
- "toml",
- "yaml-rust",
+ "crypto-common",
+ "inout",
 ]
 
 [[package]]
 name = "cookie"
-version = "0.16.1"
+version = "0.17.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "344adc371239ef32293cb1c4fe519592fcf21206c79c02854320afcdf3ab4917"
+checksum = "7efb37c3e1ccb1ff97164ad95ac1606e8ccd35b3fa0a7d99a304c7f4a428cc24"
 dependencies = [
+ "aes-gcm",
+ "base64 0.21.2",
+ "hmac",
  "percent-encoding",
- "time 0.3.17",
+ "rand 0.8.5",
+ "sha2",
+ "subtle",
+ "time 0.3.22",
  "version_check",
 ]
 
-[[package]]
-name = "core-foundation"
-version = "0.9.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146"
-dependencies = [
- "core-foundation-sys",
- "libc",
-]
-
 [[package]]
 name = "core-foundation-sys"
-version = "0.8.3"
+version = "0.8.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
+checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa"
 
 [[package]]
 name = "cpufeatures"
-version = "0.2.5"
+version = "0.2.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320"
+checksum = "03e69e28e9f7f77debdedbaafa2866e1de9ba56df55a8bd7cfc724c25a09987c"
 dependencies = [
  "libc",
 ]
 
 [[package]]
 name = "crc"
-version = "3.0.0"
+version = "3.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "53757d12b596c16c78b83458d732a5d1a17ab3f53f2f7412f6fb57cc8a140ab3"
+checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe"
 dependencies = [
  "crc-catalog",
 ]
 
 [[package]]
 name = "crc-catalog"
-version = "2.1.0"
+version = "2.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2d0165d2900ae6778e36e80bbc4da3b5eefccee9ba939761f9c2882a5d9af3ff"
+checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484"
 
 [[package]]
 name = "crc32fast"
@@ -326,18 +356,18 @@ dependencies = [
 
 [[package]]
 name = "crossbeam-utils"
-version = "0.8.14"
+version = "0.8.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f"
+checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294"
 dependencies = [
  "cfg-if",
 ]
 
 [[package]]
 name = "cruet"
-version = "0.13.2"
+version = "0.13.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4e0d174765c7d11eb16f70a4213583aac2ca5ae1ebd1e233c6d5104bfb70fce3"
+checksum = "113a9e83d8f614be76de8df1f25bf9d0ea6e85ea573710a3d3f3abe1438ae49c"
 dependencies = [
  "once_cell",
  "regex",
@@ -350,93 +380,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
 dependencies = [
  "generic-array",
+ "rand_core 0.6.4",
  "typenum",
 ]
 
 [[package]]
-name = "cxx"
-version = "1.0.86"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "51d1075c37807dcf850c379432f0df05ba52cc30f279c5cfc43cc221ce7f8579"
-dependencies = [
- "cc",
- "cxxbridge-flags",
- "cxxbridge-macro",
- "link-cplusplus",
-]
-
-[[package]]
-name = "cxx-build"
-version = "1.0.86"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5044281f61b27bc598f2f6647d480aed48d2bf52d6eb0b627d84c0361b17aa70"
-dependencies = [
- "cc",
- "codespan-reporting",
- "once_cell",
- "proc-macro2",
- "quote",
- "scratch",
- "syn",
-]
-
-[[package]]
-name = "cxxbridge-flags"
-version = "1.0.86"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "61b50bc93ba22c27b0d31128d2d130a0a6b3d267ae27ef7e4fae2167dfe8781c"
-
-[[package]]
-name = "cxxbridge-macro"
-version = "1.0.86"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "39e61fda7e62115119469c7b3591fd913ecca96fb766cfd3f2e2502ab7bc87a5"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "darling"
-version = "0.14.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b0dd3cd20dc6b5a876612a6e5accfe7f3dd883db6d07acfbf14c128f61550dfa"
-dependencies = [
- "darling_core",
- "darling_macro",
-]
-
-[[package]]
-name = "darling_core"
-version = "0.14.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a784d2ccaf7c98501746bf0be29b2022ba41fd62a2e622af997a03e9f972859f"
-dependencies = [
- "fnv",
- "ident_case",
- "proc-macro2",
- "quote",
- "strsim",
- "syn",
-]
-
-[[package]]
-name = "darling_macro"
-version = "0.14.2"
+name = "ctr"
+version = "0.9.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7618812407e9402654622dd402b0a89dff9ba93badd6540781526117b92aab7e"
+checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835"
 dependencies = [
- "darling_core",
- "quote",
- "syn",
+ "cipher",
 ]
 
 [[package]]
 name = "digest"
-version = "0.10.6"
+version = "0.10.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f"
+checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
 dependencies = [
  "block-buffer",
  "crypto-common",
@@ -463,51 +424,45 @@ dependencies = [
  "winapi",
 ]
 
-[[package]]
-name = "dlv-list"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257"
-
 [[package]]
 name = "dotenvy"
-version = "0.15.6"
+version = "0.15.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "03d8c417d7a8cb362e0c37e5d815f5eb7c37f79ff93707329d5a194e42e54ca0"
+checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b"
 
 [[package]]
 name = "either"
-version = "1.8.0"
+version = "1.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
+checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
 
 [[package]]
 name = "encoding_rs"
-version = "0.8.31"
+version = "0.8.32"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b"
+checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394"
 dependencies = [
  "cfg-if",
 ]
 
 [[package]]
 name = "enumflags2"
-version = "0.7.5"
+version = "0.7.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e75d4cd21b95383444831539909fbb14b9dc3fdceb2a6f5d36577329a1f55ccb"
+checksum = "c041f5090df68b32bcd905365fd51769c8b9d553fe87fde0b683534f10c01bd2"
 dependencies = [
  "enumflags2_derive",
 ]
 
 [[package]]
 name = "enumflags2_derive"
-version = "0.7.4"
+version = "0.7.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f58dc3c5e468259f19f2d46304a6b28f1c3d034442e14b322d2b850e36f6d5ae"
+checksum = "5e9a1f9f7d83e59740248a6e14ecf93929ade55027844dfcea78beafccc15745"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 2.0.22",
 ]
 
 [[package]]
@@ -516,25 +471,65 @@ version = "0.1.0"
 dependencies = [
  "chrono",
  "chrono-humanize",
- "config",
+ "figment",
  "lazy_static",
+ "magic",
  "nanoid",
  "once_cell",
  "ramhorns",
  "rand 0.8.5",
  "salvo",
+ "serde",
+ "serde_derive",
  "sqlx",
  "tokio",
  "tracing",
  "tracing-subscriber",
- "tree_magic_mini",
+]
+
+[[package]]
+name = "equivalent"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "88bffebc5d80432c9b140ee17875ff173a8ab62faad5b257da912bd2f6c1c0a1"
+
+[[package]]
+name = "errno"
+version = "0.2.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1"
+dependencies = [
+ "errno-dragonfly",
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "errno"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a"
+dependencies = [
+ "errno-dragonfly",
+ "libc",
+ "windows-sys",
+]
+
+[[package]]
+name = "errno-dragonfly"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
+dependencies = [
+ "cc",
+ "libc",
 ]
 
 [[package]]
 name = "etag"
-version = "3.0.0"
+version = "4.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aec9f8918ec91bd35f3068e33da01b72a295ac8a7baacb0290b56ffeeec9d88f"
+checksum = "4b3d0661a2ccddc26cba0b834e9b717959ed6fdd76c7129ee159c170a875bf44"
 dependencies = [
  "str-buf",
  "xxhash-rust",
@@ -548,24 +543,31 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
 
 [[package]]
 name = "fastrand"
-version = "1.8.0"
+version = "1.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499"
+checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be"
 dependencies = [
  "instant",
 ]
 
 [[package]]
-name = "fixedbitset"
-version = "0.4.2"
+name = "figment"
+version = "0.10.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
+checksum = "4547e226f4c9ab860571e070a9034192b3175580ecea38da34fcdb53a018c9a5"
+dependencies = [
+ "atomic",
+ "serde",
+ "toml",
+ "uncased",
+ "version_check",
+]
 
 [[package]]
 name = "flate2"
-version = "1.0.25"
+version = "1.0.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841"
+checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743"
 dependencies = [
  "crc32fast",
  "miniz_oxide",
@@ -580,7 +582,7 @@ dependencies = [
  "futures-core",
  "futures-sink",
  "pin-project",
- "spin 0.9.4",
+ "spin 0.9.8",
 ]
 
 [[package]]
@@ -591,18 +593,18 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
 
 [[package]]
 name = "form_urlencoded"
-version = "1.1.0"
+version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8"
+checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652"
 dependencies = [
  "percent-encoding",
 ]
 
 [[package]]
 name = "futures-channel"
-version = "0.3.25"
+version = "0.3.28"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed"
+checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2"
 dependencies = [
  "futures-core",
  "futures-sink",
@@ -610,15 +612,15 @@ dependencies = [
 
 [[package]]
 name = "futures-core"
-version = "0.3.25"
+version = "0.3.28"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac"
+checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c"
 
 [[package]]
 name = "futures-executor"
-version = "0.3.25"
+version = "0.3.28"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7acc85df6714c176ab5edf386123fafe217be88c0840ec11f199441134a074e2"
+checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0"
 dependencies = [
  "futures-core",
  "futures-task",
@@ -638,38 +640,38 @@ dependencies = [
 
 [[package]]
 name = "futures-io"
-version = "0.3.25"
+version = "0.3.28"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb"
+checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964"
 
 [[package]]
 name = "futures-macro"
-version = "0.3.25"
+version = "0.3.28"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d"
+checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 2.0.22",
 ]
 
 [[package]]
 name = "futures-sink"
-version = "0.3.25"
+version = "0.3.28"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9"
+checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e"
 
 [[package]]
 name = "futures-task"
-version = "0.3.25"
+version = "0.3.28"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea"
+checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65"
 
 [[package]]
 name = "futures-util"
-version = "0.3.25"
+version = "0.3.28"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6"
+checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533"
 dependencies = [
  "futures-core",
  "futures-io",
@@ -684,9 +686,9 @@ dependencies = [
 
 [[package]]
 name = "generic-array"
-version = "0.14.6"
+version = "0.14.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9"
+checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
 dependencies = [
  "typenum",
  "version_check",
@@ -705,20 +707,30 @@ dependencies = [
 
 [[package]]
 name = "getrandom"
-version = "0.2.8"
+version = "0.2.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
+checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
 dependencies = [
  "cfg-if",
  "libc",
  "wasi 0.11.0+wasi-snapshot-preview1",
 ]
 
+[[package]]
+name = "ghash"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d930750de5717d2dd0b8c0d42c076c0e884c81a73e6cab859bbd2339c71e3e40"
+dependencies = [
+ "opaque-debug",
+ "polyval",
+]
+
 [[package]]
 name = "h2"
-version = "0.3.15"
+version = "0.3.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4"
+checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049"
 dependencies = [
  "bytes",
  "fnv",
@@ -726,7 +738,7 @@ dependencies = [
  "futures-sink",
  "futures-util",
  "http",
- "indexmap",
+ "indexmap 1.9.3",
  "slab",
  "tokio",
  "tokio-util",
@@ -738,17 +750,24 @@ name = "hashbrown"
 version = "0.12.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
+
+[[package]]
+name = "hashbrown"
+version = "0.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a"
 dependencies = [
- "ahash",
+ "ahash 0.8.3",
+ "allocator-api2",
 ]
 
 [[package]]
 name = "hashlink"
-version = "0.8.1"
+version = "0.8.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "69fe1fcf8b4278d860ad0548329f892a3631fb63f82574df68275f34cdbe0ffa"
+checksum = "312f66718a2d7789ffef4f4b7b213138ed9f1eb3aa1d0d82fc99f88fb3ffd26f"
 dependencies = [
- "hashbrown",
+ "hashbrown 0.14.0",
 ]
 
 [[package]]
@@ -787,22 +806,28 @@ dependencies = [
 
 [[package]]
 name = "heck"
-version = "0.4.0"
+version = "0.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
+checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
 dependencies = [
  "unicode-segmentation",
 ]
 
 [[package]]
 name = "hermit-abi"
-version = "0.1.19"
+version = "0.2.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
+checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
 dependencies = [
  "libc",
 ]
 
+[[package]]
+name = "hermit-abi"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
+
 [[package]]
 name = "hex"
 version = "0.4.3"
@@ -829,9 +854,9 @@ dependencies = [
 
 [[package]]
 name = "http"
-version = "0.2.8"
+version = "0.2.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399"
+checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482"
 dependencies = [
  "bytes",
  "fnv",
@@ -840,12 +865,24 @@ dependencies = [
 
 [[package]]
 name = "http-body"
-version = "0.4.5"
+version = "1.0.0-rc.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "951dfc2e32ac02d67c90c0d65bd27009a635dc9b381a2cc7d284ab01e3a0150d"
+dependencies = [
+ "bytes",
+ "http",
+]
+
+[[package]]
+name = "http-body-util"
+version = "0.1.0-rc.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
+checksum = "92445bc9cc14bfa0a3ce56817dc3b5bcc227a168781a356b702410789cec0d10"
 dependencies = [
  "bytes",
+ "futures-util",
  "http",
+ "http-body",
  "pin-project-lite",
 ]
 
@@ -863,9 +900,9 @@ checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
 
 [[package]]
 name = "hyper"
-version = "0.14.23"
+version = "1.0.0-rc.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "034711faac9d2166cb1baf1a2fb0b60b1f277f8492fd72176c17f3515e1abd3c"
+checksum = "7b75264b2003a3913f118d35c586e535293b3e22e41f074930762929d071e092"
 dependencies = [
  "bytes",
  "futures-channel",
@@ -878,64 +915,39 @@ dependencies = [
  "httpdate",
  "itoa",
  "pin-project-lite",
- "socket2",
  "tokio",
- "tower-service",
  "tracing",
  "want",
 ]
 
-[[package]]
-name = "hyper-rustls"
-version = "0.23.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1788965e61b367cd03a62950836d5cd41560c3577d90e40e0819373194d1661c"
-dependencies = [
- "http",
- "hyper",
- "log",
- "rustls",
- "rustls-native-certs",
- "tokio",
- "tokio-rustls",
- "webpki-roots",
-]
-
 [[package]]
 name = "iana-time-zone"
-version = "0.1.53"
+version = "0.1.57"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765"
+checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613"
 dependencies = [
  "android_system_properties",
  "core-foundation-sys",
  "iana-time-zone-haiku",
  "js-sys",
  "wasm-bindgen",
- "winapi",
+ "windows",
 ]
 
 [[package]]
 name = "iana-time-zone-haiku"
-version = "0.1.1"
+version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca"
+checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
 dependencies = [
- "cxx",
- "cxx-build",
+ "cc",
 ]
 
-[[package]]
-name = "ident_case"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
-
 [[package]]
 name = "idna"
-version = "0.3.0"
+version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6"
+checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c"
 dependencies = [
  "unicode-bidi",
  "unicode-normalization",
@@ -943,12 +955,31 @@ dependencies = [
 
 [[package]]
 name = "indexmap"
-version = "1.9.2"
+version = "1.9.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399"
+checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
 dependencies = [
  "autocfg",
- "hashbrown",
+ "hashbrown 0.12.3",
+]
+
+[[package]]
+name = "indexmap"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d"
+dependencies = [
+ "equivalent",
+ "hashbrown 0.14.0",
+]
+
+[[package]]
+name = "inout"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5"
+dependencies = [
+ "generic-array",
 ]
 
 [[package]]
@@ -960,6 +991,17 @@ dependencies = [
  "cfg-if",
 ]
 
+[[package]]
+name = "io-lifetimes"
+version = "1.0.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2"
+dependencies = [
+ "hermit-abi 0.3.1",
+ "libc",
+ "windows-sys",
+]
+
 [[package]]
 name = "itertools"
 version = "0.10.5"
@@ -971,37 +1013,35 @@ dependencies = [
 
 [[package]]
 name = "itoa"
-version = "1.0.4"
+version = "1.0.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc"
+checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
 
 [[package]]
-name = "js-sys"
-version = "0.3.60"
+name = "jobserver"
+version = "0.1.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47"
+checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2"
 dependencies = [
- "wasm-bindgen",
+ "libc",
 ]
 
 [[package]]
-name = "json5"
-version = "0.4.1"
+name = "js-sys"
+version = "0.3.64"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1"
+checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a"
 dependencies = [
- "pest",
- "pest_derive",
- "serde",
+ "wasm-bindgen",
 ]
 
 [[package]]
 name = "jsonwebtoken"
-version = "8.2.0"
+version = "8.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09f4f04699947111ec1733e71778d763555737579e44b85844cae8e1940a1828"
+checksum = "6971da4d9c3aa03c3d8f3ff0f4155b534aad021292003895a469716b2a230378"
 dependencies = [
- "base64 0.13.1",
+ "base64 0.21.2",
  "pem",
  "ring",
  "serde",
@@ -1017,9 +1057,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
 
 [[package]]
 name = "libc"
-version = "0.2.138"
+version = "0.2.147"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8"
+checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
 
 [[package]]
 name = "libsqlite3-sys"
@@ -1033,25 +1073,16 @@ dependencies = [
 ]
 
 [[package]]
-name = "link-cplusplus"
-version = "1.0.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5"
-dependencies = [
- "cc",
-]
-
-[[package]]
-name = "linked-hash-map"
-version = "0.5.6"
+name = "linux-raw-sys"
+version = "0.3.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
+checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519"
 
 [[package]]
 name = "lock_api"
-version = "0.4.9"
+version = "0.4.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df"
+checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16"
 dependencies = [
  "autocfg",
  "scopeguard",
@@ -1059,12 +1090,9 @@ dependencies = [
 
 [[package]]
 name = "log"
-version = "0.4.17"
+version = "0.4.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
-dependencies = [
- "cfg-if",
-]
+checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4"
 
 [[package]]
 name = "logos"
@@ -1085,8 +1113,31 @@ dependencies = [
  "fnv",
  "proc-macro2",
  "quote",
- "regex-syntax",
- "syn",
+ "regex-syntax 0.6.29",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "magic"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "87142e3acb1f4daa62eaea96605421a534119d4777a9fb43fb2784798fd89665"
+dependencies = [
+ "bitflags",
+ "errno 0.2.8",
+ "libc",
+ "magic-sys",
+ "thiserror",
+]
+
+[[package]]
+name = "magic-sys"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eff86ae08895140d628119d407d568f3b657145ee8c265878064f717534bb3bc"
+dependencies = [
+ "libc",
+ "vcpkg",
 ]
 
 [[package]]
@@ -1115,9 +1166,9 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
 
 [[package]]
 name = "mime"
-version = "0.3.16"
+version = "0.3.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
+checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
 
 [[package]]
 name = "mime_guess"
@@ -1137,30 +1188,29 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
 
 [[package]]
 name = "miniz_oxide"
-version = "0.6.2"
+version = "0.7.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa"
+checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7"
 dependencies = [
  "adler",
 ]
 
 [[package]]
 name = "mio"
-version = "0.8.5"
+version = "0.8.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de"
+checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2"
 dependencies = [
  "libc",
- "log",
  "wasi 0.11.0+wasi-snapshot-preview1",
- "windows-sys 0.42.0",
+ "windows-sys",
 ]
 
 [[package]]
 name = "multer"
-version = "2.0.4"
+version = "2.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ed4198ce7a4cbd2a57af78d28c6fbb57d81ac5f1d6ad79ac6c5587419cbdf22"
+checksum = "01acbdc23469fd8fe07ab135923371d5f5a422fbf9c522158677c8eb15bc51c2"
 dependencies = [
  "bytes",
  "encoding_rs",
@@ -1170,15 +1220,15 @@ dependencies = [
  "log",
  "memchr",
  "mime",
- "spin 0.9.4",
+ "spin 0.9.8",
  "version_check",
 ]
 
 [[package]]
 name = "multimap"
-version = "0.8.3"
+version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a"
+checksum = "70db9248a93dc36a36d9a47898caa007a32755c7ad140ec64eeeb50d5a730631"
 dependencies = [
  "serde",
 ]
@@ -1194,9 +1244,9 @@ dependencies = [
 
 [[package]]
 name = "nom"
-version = "7.1.1"
+version = "7.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36"
+checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
 dependencies = [
  "memchr",
  "minimal-lexical",
@@ -1244,35 +1294,25 @@ dependencies = [
 
 [[package]]
 name = "num_cpus"
-version = "1.14.0"
+version = "1.15.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5"
+checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
 dependencies = [
- "hermit-abi",
+ "hermit-abi 0.2.6",
  "libc",
 ]
 
 [[package]]
 name = "once_cell"
-version = "1.16.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860"
-
-[[package]]
-name = "openssl-probe"
-version = "0.1.5"
+version = "1.18.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
+checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
 
 [[package]]
-name = "ordered-multimap"
-version = "0.4.3"
+name = "opaque-debug"
+version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ccd746e37177e1711c20dd619a1620f34f5c8b569c53590a72dedd5344d8924a"
-dependencies = [
- "dlv-list",
- "hashbrown",
-]
+checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
 
 [[package]]
 name = "overload"
@@ -1298,7 +1338,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
 dependencies = [
  "lock_api",
- "parking_lot_core 0.9.5",
+ "parking_lot_core 0.9.8",
 ]
 
 [[package]]
@@ -1310,29 +1350,29 @@ dependencies = [
  "cfg-if",
  "instant",
  "libc",
- "redox_syscall",
+ "redox_syscall 0.2.16",
  "smallvec",
  "winapi",
 ]
 
 [[package]]
 name = "parking_lot_core"
-version = "0.9.5"
+version = "0.9.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ff9f3fef3968a3ec5945535ed654cb38ff72d7495a25619e2247fb15a2ed9ba"
+checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447"
 dependencies = [
  "cfg-if",
  "libc",
- "redox_syscall",
+ "redox_syscall 0.3.5",
  "smallvec",
- "windows-sys 0.42.0",
+ "windows-targets",
 ]
 
 [[package]]
 name = "paste"
-version = "1.0.10"
+version = "1.0.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cf1c2c742266c2f1041c914ba65355a83ae8747b05f208319784083583494b4b"
+checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79"
 
 [[package]]
 name = "path-slash"
@@ -1340,99 +1380,39 @@ version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1e91099d4268b0e11973f036e885d652fb0b21fedcf69738c627f94db6a44f42"
 
-[[package]]
-name = "pathdiff"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd"
-
 [[package]]
 name = "pem"
-version = "1.1.0"
+version = "1.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "03c64931a1a212348ec4f3b4362585eca7159d0d09cbdf4a7f74f02173596fd4"
+checksum = "a8835c273a76a90455d7344889b0964598e3316e2a79ede8e36f16bdcf2228b8"
 dependencies = [
  "base64 0.13.1",
 ]
 
 [[package]]
 name = "percent-encoding"
-version = "2.2.0"
+version = "2.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
-
-[[package]]
-name = "pest"
-version = "2.5.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4257b4a04d91f7e9e6290be5d3da4804dd5784fafde3a497d73eb2b4a158c30a"
-dependencies = [
- "thiserror",
- "ucd-trie",
-]
-
-[[package]]
-name = "pest_derive"
-version = "2.5.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "241cda393b0cdd65e62e07e12454f1f25d57017dcc514b1514cd3c4645e3a0a6"
-dependencies = [
- "pest",
- "pest_generator",
-]
-
-[[package]]
-name = "pest_generator"
-version = "2.5.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "46b53634d8c8196302953c74d5352f33d0c512a9499bd2ce468fc9f4128fa27c"
-dependencies = [
- "pest",
- "pest_meta",
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "pest_meta"
-version = "2.5.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ef4f1332a8d4678b41966bb4cc1d0676880e84183a1ecc3f4b69f03e99c7a51"
-dependencies = [
- "once_cell",
- "pest",
- "sha2",
-]
-
-[[package]]
-name = "petgraph"
-version = "0.6.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4"
-dependencies = [
- "fixedbitset",
- "indexmap",
-]
+checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
 
 [[package]]
 name = "pin-project"
-version = "1.0.12"
+version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc"
+checksum = "c95a7476719eab1e366eaf73d0260af3021184f18177925b07f54b30089ceead"
 dependencies = [
  "pin-project-internal",
 ]
 
 [[package]]
 name = "pin-project-internal"
-version = "1.0.12"
+version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55"
+checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 2.0.22",
 ]
 
 [[package]]
@@ -1449,9 +1429,21 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
 
 [[package]]
 name = "pkg-config"
-version = "0.3.26"
+version = "0.3.27"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160"
+checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
+
+[[package]]
+name = "polyval"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d52cff9d1d4dee5fe6d03729099f4a310a41179e0a10dbf542039873f2e826fb"
+dependencies = [
+ "cfg-if",
+ "cpufeatures",
+ "opaque-debug",
+ "universal-hash",
+]
 
 [[package]]
 name = "ppv-lite86"
@@ -1461,13 +1453,12 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
 
 [[package]]
 name = "proc-macro-crate"
-version = "1.2.1"
+version = "1.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eda0fc3b0fb7c975631757e14d9049da17374063edb6ebbcbc54d880d4fe94e9"
+checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919"
 dependencies = [
  "once_cell",
- "thiserror",
- "toml",
+ "toml_edit",
 ]
 
 [[package]]
@@ -1479,7 +1470,7 @@ dependencies = [
  "proc-macro-error-attr",
  "proc-macro2",
  "quote",
- "syn",
+ "syn 1.0.109",
  "version_check",
 ]
 
@@ -1496,18 +1487,18 @@ dependencies = [
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.54"
+version = "1.0.63"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e472a104799c74b514a57226160104aa483546de37e839ec50e3c2e41dd87534"
+checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb"
 dependencies = [
  "unicode-ident",
 ]
 
 [[package]]
 name = "pulldown-cmark"
-version = "0.9.2"
+version = "0.9.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2d9cc634bc78768157b5cbfe988ffcd1dcba95cd2b2f03a88316c08c6d00ed63"
+checksum = "77a1a2f1f0a7ecff9c31abbe177637be0e97a0aef46cf8738ece09327985d998"
 dependencies = [
  "bitflags",
  "memchr",
@@ -1516,9 +1507,9 @@ dependencies = [
 
 [[package]]
 name = "quote"
-version = "1.0.26"
+version = "1.0.28"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc"
+checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488"
 dependencies = [
  "proc-macro2",
 ]
@@ -1547,7 +1538,7 @@ dependencies = [
  "fnv",
  "proc-macro2",
  "quote",
- "syn",
+ "syn 1.0.109",
 ]
 
 [[package]]
@@ -1609,7 +1600,7 @@ version = "0.6.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
 dependencies = [
- "getrandom 0.2.8",
+ "getrandom 0.2.10",
 ]
 
 [[package]]
@@ -1630,26 +1621,35 @@ dependencies = [
  "bitflags",
 ]
 
+[[package]]
+name = "redox_syscall"
+version = "0.3.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
+dependencies = [
+ "bitflags",
+]
+
 [[package]]
 name = "redox_users"
 version = "0.4.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
 dependencies = [
- "getrandom 0.2.8",
- "redox_syscall",
+ "getrandom 0.2.10",
+ "redox_syscall 0.2.16",
  "thiserror",
 ]
 
 [[package]]
 name = "regex"
-version = "1.7.0"
+version = "1.8.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a"
+checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f"
 dependencies = [
  "aho-corasick",
  "memchr",
- "regex-syntax",
+ "regex-syntax 0.7.2",
 ]
 
 [[package]]
@@ -1658,23 +1658,20 @@ version = "0.1.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
 dependencies = [
- "regex-syntax",
+ "regex-syntax 0.6.29",
 ]
 
 [[package]]
 name = "regex-syntax"
-version = "0.6.28"
+version = "0.6.29"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
+checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
 
 [[package]]
-name = "remove_dir_all"
-version = "0.5.3"
+name = "regex-syntax"
+version = "0.7.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
-dependencies = [
- "winapi",
-]
+checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78"
 
 [[package]]
 name = "ring"
@@ -1691,22 +1688,11 @@ dependencies = [
  "winapi",
 ]
 
-[[package]]
-name = "ron"
-version = "0.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "88073939a61e5b7680558e6be56b419e208420c2adb92be54921fa6b72283f1a"
-dependencies = [
- "base64 0.13.1",
- "bitflags",
- "serde",
-]
-
 [[package]]
 name = "rust-embed"
-version = "6.4.2"
+version = "6.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "283ffe2f866869428c92e0d61c2f35dfb4355293cdfdc48f49e895c15f1333d1"
+checksum = "b73e721f488c353141288f223b599b4ae9303ecf3e62923f40a492f0634a4dc3"
 dependencies = [
  "rust-embed-impl",
  "rust-embed-utils",
@@ -1715,42 +1701,46 @@ dependencies = [
 
 [[package]]
 name = "rust-embed-impl"
-version = "6.3.1"
+version = "6.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "31ab23d42d71fb9be1b643fe6765d292c5e14d46912d13f3ae2815ca048ea04d"
+checksum = "e22ce362f5561923889196595504317a4372b84210e6e335da529a65ea5452b5"
 dependencies = [
  "proc-macro2",
  "quote",
  "rust-embed-utils",
- "syn",
+ "syn 2.0.22",
  "walkdir",
 ]
 
 [[package]]
 name = "rust-embed-utils"
-version = "7.3.0"
+version = "7.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c1669d81dfabd1b5f8e2856b8bbe146c6192b0ba22162edc738ac0a5de18f054"
+checksum = "512b0ab6853f7e14e3c8754acb43d6f748bb9ced66aa5915a6553ac8213f7731"
 dependencies = [
  "sha2",
  "walkdir",
 ]
 
 [[package]]
-name = "rust-ini"
-version = "0.18.0"
+name = "rustix"
+version = "0.37.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f6d5f2436026b4f6e79dc829837d467cc7e9a55ee40e750d716713540715a2df"
+checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0"
 dependencies = [
- "cfg-if",
- "ordered-multimap",
+ "bitflags",
+ "errno 0.3.1",
+ "io-lifetimes",
+ "libc",
+ "linux-raw-sys",
+ "windows-sys",
 ]
 
 [[package]]
 name = "rustls"
-version = "0.20.7"
+version = "0.20.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "539a2bfe908f471bfa933876bd1eb6a19cf2176d375f82ef7f99530a40e48c2c"
+checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f"
 dependencies = [
  "log",
  "ring",
@@ -1758,49 +1748,37 @@ dependencies = [
  "webpki",
 ]
 
-[[package]]
-name = "rustls-native-certs"
-version = "0.6.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0167bac7a9f490495f3c33013e7722b53cb087ecbe082fb0c6387c96f634ea50"
-dependencies = [
- "openssl-probe",
- "rustls-pemfile",
- "schannel",
- "security-framework",
-]
-
 [[package]]
 name = "rustls-pemfile"
-version = "1.0.1"
+version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0864aeff53f8c05aa08d86e5ef839d3dfcf07aeba2db32f12db0ef716e87bd55"
+checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b"
 dependencies = [
- "base64 0.13.1",
+ "base64 0.21.2",
 ]
 
 [[package]]
 name = "ryu"
-version = "1.0.11"
+version = "1.0.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
+checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
 
 [[package]]
 name = "salvo"
-version = "0.37.7"
+version = "0.44.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "24bcfe3ad932be5844b5c7cb4a8a6c390b120759c31e6ea065caf763119dcf1b"
+checksum = "c39d8b982850b656146908b46e99a19366aabdb51d4b4fb31ed3a17175acca27"
 dependencies = [
- "salvo-static",
+ "salvo-serve-static",
  "salvo_core",
  "salvo_extra",
 ]
 
 [[package]]
-name = "salvo-static"
-version = "0.37.7"
+name = "salvo-serve-static"
+version = "0.44.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ee2987b98760f81d3f7f2c47757f48f158f7acdbb10af0e777063463ef7fc00"
+checksum = "4c82d34d8ae23a37c4499702e2f0d2848f4ce16320b74b737f34995616c5d165"
 dependencies = [
  "hex",
  "mime",
@@ -1811,31 +1789,52 @@ dependencies = [
  "salvo_core",
  "serde",
  "serde_json",
- "time 0.3.17",
+ "time 0.3.22",
+ "tokio",
+ "tracing",
+]
+
+[[package]]
+name = "salvo-utils"
+version = "0.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fcc5955a5ab06f16e9c12e7572fb9a845571f3c6c6f60f4851e870ff112503b3"
+dependencies = [
+ "futures-channel",
+ "futures-util",
+ "http",
+ "hyper",
+ "once_cell",
+ "pin-project-lite",
+ "socket2",
  "tokio",
+ "tower",
+ "tower-service",
  "tracing",
 ]
 
 [[package]]
 name = "salvo_core"
-version = "0.37.7"
+version = "0.44.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cb1b199dd08eebadbe518beffa26b63e02b93bdf8b09bf9ecd8740b65def38c8"
+checksum = "420e9316f430f386560cb42ea12c5d014fdbaae399d64b351593957256c03490"
 dependencies = [
- "async-compression",
  "async-trait",
- "base64 0.13.1",
+ "base64 0.21.2",
+ "brotli",
  "bytes",
  "cookie",
  "cruet",
  "encoding_rs",
  "enumflags2",
- "fastrand",
+ "flate2",
  "form_urlencoded",
  "futures-util",
  "headers",
  "http",
+ "http-body-util",
  "hyper",
+ "indexmap 1.9.3",
  "mime",
  "mime_guess",
  "multer",
@@ -1843,7 +1842,9 @@ dependencies = [
  "once_cell",
  "parking_lot 0.12.1",
  "percent-encoding",
+ "pin-project",
  "regex",
+ "salvo-utils",
  "salvo_macros",
  "serde",
  "serde_json",
@@ -1855,25 +1856,25 @@ dependencies = [
  "tokio-stream",
  "tracing",
  "url",
+ "zstd",
 ]
 
 [[package]]
 name = "salvo_extra"
-version = "0.37.7"
+version = "0.44.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6726713b992b9857ed66a7ff48253b2780b0f96fc71908bc4dd2fc89c43aae6e"
+checksum = "911bd4a8f471dd7b1292845233acaedb6dd7f7b29e609cd755cfaeea695274cf"
 dependencies = [
- "async-compression",
- "base64 0.13.1",
+ "base64 0.21.2",
+ "brotli",
  "bytes",
  "etag",
- "fastrand",
+ "flate2",
  "futures-util",
  "hyper",
- "hyper-rustls",
+ "indexmap 1.9.3",
  "jsonwebtoken",
  "once_cell",
- "percent-encoding",
  "pin-project",
  "salvo_core",
  "serde",
@@ -1883,21 +1884,21 @@ dependencies = [
  "tokio-tungstenite",
  "tokio-util",
  "tracing",
+ "zstd",
 ]
 
 [[package]]
 name = "salvo_macros"
-version = "0.37.7"
+version = "0.44.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c47a031f77aadfc539253d32a79cf140b87e472abd8a8a625d3505fc3ac7b849"
+checksum = "e504e3ad06578cc6139e538f1973e92d89093c0fdcf5ec8c1abd7a53902568bb"
 dependencies = [
  "cruet",
- "darling",
  "proc-macro-crate",
  "proc-macro2",
  "quote",
  "regex",
- "syn",
+ "syn 2.0.22",
 ]
 
 [[package]]
@@ -1909,28 +1910,12 @@ dependencies = [
  "winapi-util",
 ]
 
-[[package]]
-name = "schannel"
-version = "0.1.20"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2"
-dependencies = [
- "lazy_static",
- "windows-sys 0.36.1",
-]
-
 [[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.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ddccb15bcce173023b3fedd9436f882a0739b8dfb45e4f6b6002bee5929f61b2"
-
 [[package]]
 name = "sct"
 version = "0.7.0"
@@ -1941,60 +1926,46 @@ dependencies = [
  "untrusted",
 ]
 
-[[package]]
-name = "security-framework"
-version = "2.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2bc1bb97804af6631813c55739f771071e0f2ed33ee20b68c86ec505d906356c"
-dependencies = [
- "bitflags",
- "core-foundation",
- "core-foundation-sys",
- "libc",
- "security-framework-sys",
-]
-
-[[package]]
-name = "security-framework-sys"
-version = "2.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556"
-dependencies = [
- "core-foundation-sys",
- "libc",
-]
-
 [[package]]
 name = "serde"
-version = "1.0.150"
+version = "1.0.164"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e326c9ec8042f1b5da33252c8a37e9ffbd2c9bef0155215b6e6c80c790e05f91"
+checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d"
 dependencies = [
  "serde_derive",
 ]
 
 [[package]]
 name = "serde_derive"
-version = "1.0.150"
+version = "1.0.164"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "42a3df25b0713732468deadad63ab9da1f1fd75a48a15024b50363f128db627e"
+checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 2.0.22",
 ]
 
 [[package]]
 name = "serde_json"
-version = "1.0.89"
+version = "1.0.99"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db"
+checksum = "46266871c240a00b8f503b877622fe33430b3c7d963bdc0f2adc511e54a1eae3"
 dependencies = [
  "itoa",
  "ryu",
  "serde",
 ]
 
+[[package]]
+name = "serde_spanned"
+version = "0.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186"
+dependencies = [
+ "serde",
+]
+
 [[package]]
 name = "serde_urlencoded"
 version = "0.7.1"
@@ -2007,17 +1978,6 @@ dependencies = [
  "serde",
 ]
 
-[[package]]
-name = "sha-1"
-version = "0.10.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f5058ada175748e33390e40e872bd0fe59a19f265d0158daa551c5a88a76009c"
-dependencies = [
- "cfg-if",
- "cpufeatures",
- "digest",
-]
-
 [[package]]
 name = "sha1"
 version = "0.10.5"
@@ -2031,9 +1991,9 @@ dependencies = [
 
 [[package]]
 name = "sha2"
-version = "0.10.6"
+version = "0.10.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0"
+checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8"
 dependencies = [
  "cfg-if",
  "cpufeatures",
@@ -2058,14 +2018,14 @@ dependencies = [
  "num-bigint",
  "num-traits",
  "thiserror",
- "time 0.3.17",
+ "time 0.3.22",
 ]
 
 [[package]]
 name = "slab"
-version = "0.4.7"
+version = "0.4.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef"
+checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d"
 dependencies = [
  "autocfg",
 ]
@@ -2078,9 +2038,9 @@ checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
 
 [[package]]
 name = "socket2"
-version = "0.4.7"
+version = "0.4.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd"
+checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662"
 dependencies = [
  "libc",
  "winapi",
@@ -2094,18 +2054,18 @@ checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
 
 [[package]]
 name = "spin"
-version = "0.9.4"
+version = "0.9.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f6002a767bff9e83f8eeecf883ecb8011875a21ae8da43bffb817a57e78cc09"
+checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
 dependencies = [
  "lock_api",
 ]
 
 [[package]]
 name = "sqlformat"
-version = "0.2.0"
+version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f87e292b4291f154971a43c3774364e2cbcaec599d3f5bf6fa9d122885dbc38a"
+checksum = "0c12bc9199d1db8234678b7051747c07f517cdcf019262d1847b94ec8b1aee3e"
 dependencies = [
  "itertools",
  "nom",
@@ -2114,9 +2074,9 @@ dependencies = [
 
 [[package]]
 name = "sqlx"
-version = "0.6.2"
+version = "0.6.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9249290c05928352f71c077cc44a464d880c63f26f7534728cca008e135c0428"
+checksum = "f8de3b03a925878ed54a954f621e64bf55a3c1bd29652d0d1a17830405350188"
 dependencies = [
  "sqlx-core",
  "sqlx-macros",
@@ -2124,11 +2084,11 @@ dependencies = [
 
 [[package]]
 name = "sqlx-core"
-version = "0.6.2"
+version = "0.6.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dcbc16ddba161afc99e14d1713a453747a2b07fc097d2009f4c300ec99286105"
+checksum = "fa8241483a83a3f33aa5fff7e7d9def398ff9990b2752b6c6112b83c6d246029"
 dependencies = [
- "ahash",
+ "ahash 0.7.6",
  "atoi",
  "base64 0.13.1",
  "bitflags",
@@ -2150,7 +2110,7 @@ dependencies = [
  "hex",
  "hkdf",
  "hmac",
- "indexmap",
+ "indexmap 1.9.3",
  "itoa",
  "libc",
  "libsqlite3-sys",
@@ -2180,28 +2140,28 @@ dependencies = [
 
 [[package]]
 name = "sqlx-macros"
-version = "0.6.2"
+version = "0.6.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b850fa514dc11f2ee85be9d055c512aa866746adfacd1cb42d867d68e6a5b0d9"
+checksum = "9966e64ae989e7e575b19d7265cb79d7fc3cbbdf179835cb0d716f294c2049c9"
 dependencies = [
  "dotenvy",
  "either",
- "heck 0.4.0",
+ "heck 0.4.1",
  "once_cell",
  "proc-macro2",
  "quote",
  "sha2",
  "sqlx-core",
  "sqlx-rt",
- "syn",
+ "syn 1.0.109",
  "url",
 ]
 
 [[package]]
 name = "sqlx-rt"
-version = "0.6.2"
+version = "0.6.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "24c5b2d25fa654cc5f841750b8e1cdedbe21189bf9a9382ee90bfa9dd3562396"
+checksum = "804d3f245f894e61b1e6263c84b23ca675d96753b5abfd5cc8597d86806e8024"
 dependencies = [
  "once_cell",
  "tokio",
@@ -2210,9 +2170,9 @@ dependencies = [
 
 [[package]]
 name = "str-buf"
-version = "2.0.5"
+version = "3.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0873cb29201126440dcc78d0b1f5a13d917e78831778429a7920ca9c7f3dae1e"
+checksum = "e75b72ee54e2f93c3ea1354066162be893ee5e25773ab743de3e088cecbb4f31"
 
 [[package]]
 name = "stringprep"
@@ -2224,23 +2184,17 @@ dependencies = [
  "unicode-normalization",
 ]
 
-[[package]]
-name = "strsim"
-version = "0.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
-
 [[package]]
 name = "subtle"
-version = "2.4.1"
+version = "2.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
+checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
 
 [[package]]
 name = "syn"
-version = "1.0.105"
+version = "1.0.109"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908"
+checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -2248,26 +2202,28 @@ dependencies = [
 ]
 
 [[package]]
-name = "tempfile"
-version = "3.3.0"
+name = "syn"
+version = "2.0.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4"
+checksum = "2efbeae7acf4eabd6bcdcbd11c92f45231ddda7539edc7806bd1a04a03b24616"
 dependencies = [
- "cfg-if",
- "fastrand",
- "libc",
- "redox_syscall",
- "remove_dir_all",
- "winapi",
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
 ]
 
 [[package]]
-name = "termcolor"
-version = "1.1.3"
+name = "tempfile"
+version = "3.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
+checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6"
 dependencies = [
- "winapi-util",
+ "autocfg",
+ "cfg-if",
+ "fastrand",
+ "redox_syscall 0.3.5",
+ "rustix",
+ "windows-sys",
 ]
 
 [[package]]
@@ -2282,30 +2238,31 @@ dependencies = [
 
 [[package]]
 name = "thiserror"
-version = "1.0.37"
+version = "1.0.40"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e"
+checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac"
 dependencies = [
  "thiserror-impl",
 ]
 
 [[package]]
 name = "thiserror-impl"
-version = "1.0.37"
+version = "1.0.40"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb"
+checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 2.0.22",
 ]
 
 [[package]]
 name = "thread_local"
-version = "1.1.4"
+version = "1.1.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180"
+checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152"
 dependencies = [
+ "cfg-if",
  "once_cell",
 ]
 
@@ -2322,9 +2279,9 @@ dependencies = [
 
 [[package]]
 name = "time"
-version = "0.3.17"
+version = "0.3.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376"
+checksum = "ea9e1b3cf1243ae005d9e74085d4d542f3125458f3a81af210d901dcd7411efd"
 dependencies = [
  "itoa",
  "serde",
@@ -2334,15 +2291,15 @@ dependencies = [
 
 [[package]]
 name = "time-core"
-version = "0.1.0"
+version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd"
+checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb"
 
 [[package]]
 name = "time-macros"
-version = "0.2.6"
+version = "0.2.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2"
+checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b"
 dependencies = [
  "time-core",
 ]
@@ -2358,37 +2315,36 @@ dependencies = [
 
 [[package]]
 name = "tinyvec_macros"
-version = "0.1.0"
+version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
+checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
 
 [[package]]
 name = "tokio"
-version = "1.23.0"
+version = "1.28.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eab6d665857cc6ca78d6e80303a02cea7a7851e85dfbd77cbdc09bd129f1ef46"
+checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2"
 dependencies = [
  "autocfg",
  "bytes",
  "libc",
- "memchr",
  "mio",
  "num_cpus",
  "pin-project-lite",
  "socket2",
  "tokio-macros",
- "windows-sys 0.42.0",
+ "windows-sys",
 ]
 
 [[package]]
 name = "tokio-macros"
-version = "1.8.2"
+version = "2.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8"
+checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 2.0.22",
 ]
 
 [[package]]
@@ -2404,9 +2360,9 @@ dependencies = [
 
 [[package]]
 name = "tokio-stream"
-version = "0.1.11"
+version = "0.1.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d660770404473ccd7bc9f8b28494a811bc18542b915c0855c51e8f419d5223ce"
+checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842"
 dependencies = [
  "futures-core",
  "pin-project-lite",
@@ -2415,9 +2371,9 @@ dependencies = [
 
 [[package]]
 name = "tokio-tungstenite"
-version = "0.17.2"
+version = "0.19.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f714dd15bead90401d77e04243611caec13726c2408afd5b31901dfcdcb3b181"
+checksum = "ec509ac96e9a0c43427c74f003127d953a265737636129424288d27cb5c4b12c"
 dependencies = [
  "futures-util",
  "log",
@@ -2427,9 +2383,9 @@ dependencies = [
 
 [[package]]
 name = "tokio-util"
-version = "0.7.4"
+version = "0.7.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740"
+checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d"
 dependencies = [
  "bytes",
  "futures-core",
@@ -2441,13 +2397,60 @@ dependencies = [
 
 [[package]]
 name = "toml"
-version = "0.5.9"
+version = "0.7.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1ebafdf5ad1220cb59e7d17cf4d2c72015297b75b19a10472f99b89225089240"
+dependencies = [
+ "serde",
+ "serde_spanned",
+ "toml_datetime",
+ "toml_edit",
+]
+
+[[package]]
+name = "toml_datetime"
+version = "0.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "toml_edit"
+version = "0.19.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7"
+checksum = "266f016b7f039eec8a1a80dfe6156b633d208b9fccca5e4db1d6775b0c4e34a7"
 dependencies = [
+ "indexmap 2.0.0",
  "serde",
+ "serde_spanned",
+ "toml_datetime",
+ "winnow",
+]
+
+[[package]]
+name = "tower"
+version = "0.4.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c"
+dependencies = [
+ "futures-core",
+ "futures-util",
+ "pin-project",
+ "pin-project-lite",
+ "tokio",
+ "tower-layer",
+ "tower-service",
+ "tracing",
 ]
 
+[[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.2"
@@ -2461,6 +2464,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
 dependencies = [
  "cfg-if",
+ "log",
  "pin-project-lite",
  "tracing-attributes",
  "tracing-core",
@@ -2468,20 +2472,20 @@ dependencies = [
 
 [[package]]
 name = "tracing-attributes"
-version = "0.1.23"
+version = "0.1.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a"
+checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 2.0.22",
 ]
 
 [[package]]
 name = "tracing-core"
-version = "0.1.30"
+version = "0.1.31"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a"
+checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a"
 dependencies = [
  "once_cell",
  "valuable",
@@ -2500,9 +2504,9 @@ dependencies = [
 
 [[package]]
 name = "tracing-subscriber"
-version = "0.3.16"
+version = "0.3.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70"
+checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77"
 dependencies = [
  "matchers",
  "nu-ansi-term",
@@ -2516,42 +2520,23 @@ dependencies = [
  "tracing-log",
 ]
 
-[[package]]
-name = "tree_magic_mini"
-version = "3.0.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "91adfd0607cacf6e4babdb870e9bec4037c1c4b151cfd279ccefc5e0c7feaa6d"
-dependencies = [
- "bytecount",
- "fnv",
- "lazy_static",
- "nom",
- "once_cell",
- "petgraph",
-]
-
 [[package]]
 name = "try-lock"
-version = "0.2.3"
+version = "0.2.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
+checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed"
 
 [[package]]
 name = "tungstenite"
-version = "0.17.3"
+version = "0.19.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e27992fd6a8c29ee7eef28fc78349aa244134e10ad447ce3b9f0ac0ed0fa4ce0"
+checksum = "15fba1a6d6bb030745759a9a2a588bfe8490fc8b4751a277db3a0be1c9ebbf67"
 dependencies = [
- "base64 0.13.1",
  "byteorder",
  "bytes",
- "http",
- "httparse",
  "log",
  "rand 0.8.5",
- "sha-1",
  "thiserror",
- "url",
  "utf-8",
 ]
 
@@ -2562,10 +2547,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
 
 [[package]]
-name = "ucd-trie"
-version = "0.1.5"
+name = "uncased"
+version = "0.9.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81"
+checksum = "9b9bc53168a4be7402ab86c3aad243a84dd7381d09be0eddc81280c1da95ca68"
+dependencies = [
+ "version_check",
+]
 
 [[package]]
 name = "unicase"
@@ -2578,15 +2566,15 @@ dependencies = [
 
 [[package]]
 name = "unicode-bidi"
-version = "0.3.8"
+version = "0.3.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"
+checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
 
 [[package]]
 name = "unicode-ident"
-version = "1.0.5"
+version = "1.0.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
+checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0"
 
 [[package]]
 name = "unicode-normalization"
@@ -2599,15 +2587,9 @@ dependencies = [
 
 [[package]]
 name = "unicode-segmentation"
-version = "1.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a"
-
-[[package]]
-name = "unicode-width"
-version = "0.1.10"
+version = "1.10.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
+checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
 
 [[package]]
 name = "unicode_categories"
@@ -2615,6 +2597,16 @@ version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
 
+[[package]]
+name = "universal-hash"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea"
+dependencies = [
+ "crypto-common",
+ "subtle",
+]
+
 [[package]]
 name = "untrusted"
 version = "0.7.1"
@@ -2623,9 +2615,9 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
 
 [[package]]
 name = "url"
-version = "2.3.1"
+version = "2.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643"
+checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb"
 dependencies = [
  "form_urlencoded",
  "idna",
@@ -2658,22 +2650,20 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
 
 [[package]]
 name = "walkdir"
-version = "2.3.2"
+version = "2.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56"
+checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698"
 dependencies = [
  "same-file",
- "winapi",
  "winapi-util",
 ]
 
 [[package]]
 name = "want"
-version = "0.3.0"
+version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0"
+checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
 dependencies = [
- "log",
  "try-lock",
 ]
 
@@ -2697,9 +2687,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
 
 [[package]]
 name = "wasm-bindgen"
-version = "0.2.83"
+version = "0.2.87"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268"
+checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342"
 dependencies = [
  "cfg-if",
  "wasm-bindgen-macro",
@@ -2707,24 +2697,24 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-backend"
-version = "0.2.83"
+version = "0.2.87"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142"
+checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd"
 dependencies = [
  "bumpalo",
  "log",
  "once_cell",
  "proc-macro2",
  "quote",
- "syn",
+ "syn 2.0.22",
  "wasm-bindgen-shared",
 ]
 
 [[package]]
 name = "wasm-bindgen-macro"
-version = "0.2.83"
+version = "0.2.87"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810"
+checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d"
 dependencies = [
  "quote",
  "wasm-bindgen-macro-support",
@@ -2732,28 +2722,28 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-macro-support"
-version = "0.2.83"
+version = "0.2.87"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c"
+checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 2.0.22",
  "wasm-bindgen-backend",
  "wasm-bindgen-shared",
 ]
 
 [[package]]
 name = "wasm-bindgen-shared"
-version = "0.2.83"
+version = "0.2.87"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f"
+checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1"
 
 [[package]]
 name = "web-sys"
-version = "0.3.60"
+version = "0.3.64"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f"
+checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b"
 dependencies = [
  "js-sys",
  "wasm-bindgen",
@@ -2780,9 +2770,9 @@ dependencies = [
 
 [[package]]
 name = "whoami"
-version = "1.3.0"
+version = "1.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "45dbc71f0cdca27dc261a9bd37ddec174e4a0af2b900b890f378460f745426e3"
+checksum = "22fc3756b8a9133049b26c7f61ab35416c130e8c09b660f5b3958b446f52cc50"
 dependencies = [
  "wasm-bindgen",
  "web-sys",
@@ -2820,104 +2810,88 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
 
 [[package]]
-name = "windows-sys"
-version = "0.36.1"
+name = "windows"
+version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2"
+checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f"
 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",
+ "windows-targets",
 ]
 
 [[package]]
 name = "windows-sys"
-version = "0.42.0"
+version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
+checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
 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",
+ "windows-targets",
 ]
 
 [[package]]
-name = "windows_aarch64_gnullvm"
-version = "0.42.0"
+name = "windows-targets"
+version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e"
+checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5"
+dependencies = [
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc",
+]
 
 [[package]]
-name = "windows_aarch64_msvc"
-version = "0.36.1"
+name = "windows_aarch64_gnullvm"
+version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47"
+checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
 
 [[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"
+version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6"
+checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
 
 [[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"
+version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024"
+checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
 
 [[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"
+version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1"
+checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
 
 [[package]]
 name = "windows_x86_64_gnu"
-version = "0.42.0"
+version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed"
+checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
 
 [[package]]
 name = "windows_x86_64_gnullvm"
-version = "0.42.0"
+version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028"
+checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
 
 [[package]]
 name = "windows_x86_64_msvc"
-version = "0.36.1"
+version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680"
+checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
 
 [[package]]
-name = "windows_x86_64_msvc"
-version = "0.42.0"
+name = "winnow"
+version = "0.4.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5"
+checksum = "ca0ace3845f0d96209f0375e6d367e3eb87eb65d27d445bdc9f1843a26f39448"
+dependencies = [
+ "memchr",
+]
 
 [[package]]
 name = "xxhash-rust"
@@ -2926,10 +2900,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "735a71d46c4d68d71d4b24d03fdc2b98e38cea81730595801db779c04fe80d70"
 
 [[package]]
-name = "yaml-rust"
-version = "0.4.5"
+name = "zstd"
+version = "0.12.3+zstd.1.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "76eea132fb024e0e13fd9c2f5d5d595d8a967aa72382ac2f9d39fcc95afd0806"
+dependencies = [
+ "zstd-safe",
+]
+
+[[package]]
+name = "zstd-safe"
+version = "6.0.5+zstd.1.5.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d56d9e60b4b1758206c238a10165fbcae3ca37b01744e394c463463f6529d23b"
+dependencies = [
+ "libc",
+ "zstd-sys",
+]
+
+[[package]]
+name = "zstd-sys"
+version = "2.0.8+zstd.1.5.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
+checksum = "5556e6ee25d32df2586c098bbfa278803692a20d0ab9565e049480d52707ec8c"
 dependencies = [
- "linked-hash-map",
+ "cc",
+ "libc",
+ "pkg-config",
 ]
diff --git a/Cargo.toml b/Cargo.toml
index f5c7e8cffb7296177999134ee21d80b0150a92db..97a437d27eb38174a04f1525c2b020c0b4a6605a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -20,7 +20,9 @@ tracing-subscriber = { version = "0.3", features = ["env-filter"] }
 nanoid = "0.4.0"
 chrono = "0.4.23"
 rand = "0.8.5"
-config = "0.13.3"
+figment =  { version = "0.10.10", features = ["toml"] }
 lazy_static = "1.4.0"
-tree_magic_mini = "3.0.3"
 chrono-humanize = "0.2.2"
+magic = "0.13.0"
+serde_derive = "1.0.164"
+serde = "1.0.164"
diff --git a/src/config.rs b/src/config.rs
new file mode 100644
index 0000000000000000000000000000000000000000..3733643ce8bd3c7d6ac3a032abc00f6fe1d2b692
--- /dev/null
+++ b/src/config.rs
@@ -0,0 +1,42 @@
+use serde_derive::Deserialize;
+
+#[derive(Debug, Clone, Deserialize)]
+pub struct ServerConfig {
+    pub host: String,
+    pub port: u16,
+    pub nginx_sendfile: bool,
+}
+
+#[derive(Debug, Clone, Deserialize)]
+pub struct DatabaseConfig {
+    pub sql_backend: String,
+    pub url: String,
+}
+
+#[derive(Debug, Clone, Deserialize)]
+pub struct LoggingConfig {
+    pub level: String,
+    pub metrics: bool,
+}
+
+#[derive(Debug, Clone, Deserialize)]
+pub struct OperationsConfig {
+    pub filename_size: u8,
+    pub adminkey_size: u8,
+    pub apikey_size: u8,
+    pub engine_mode: i64,
+    pub cleaner_interval: i32,
+    pub file_expiry_min: u32,
+    pub file_expiry_max: u32,
+    pub max_filesize: u64,
+    pub banned_mimetype: Vec<String>,
+    pub unsafe_mimetype: Vec<String>,
+}
+
+#[derive(Debug, Clone, Deserialize)]
+pub struct AppConfig {
+    pub server: ServerConfig,
+    pub database: DatabaseConfig,
+    pub logging: LoggingConfig,
+    pub operations: OperationsConfig,
+}
diff --git a/src/db.rs b/src/db.rs
index 671d7efe389e7d0b86cfd439c7633cbeecb79901..89dae5a183356e0a34369d6d90bfe92bfb03125c 100644
--- a/src/db.rs
+++ b/src/db.rs
@@ -277,12 +277,15 @@ fn update_expiry_override() {
 
 /// This function gets a array of all the files uploaded by a specific API Key.
 /// This allows for the select few who hold an API key to view the information about the files they upload.
-pub async fn get_my_files(sqlconn: &Pool<Sqlite>, ip: &str) -> Result<Vec<FileMetric>, sqlx::Error> {
+pub async fn get_my_files(
+    sqlconn: &Pool<Sqlite>,
+    ip: &str,
+) -> Result<Vec<FileMetric>, sqlx::Error> {
     let result = sqlx::query!(
         "SELECT file, filesize, mimetype, views, expiry, expiry_override, ip, isDeleted
             FROM files
             WHERE ip = ?",
-            ip
+        ip
     )
     .fetch_all(sqlconn)
     .await?;
@@ -300,7 +303,7 @@ pub async fn get_my_files(sqlconn: &Pool<Sqlite>, ip: &str) -> Result<Vec<FileMe
             filesize: row.filesize,
             views: row.views.unwrap(),
             expiry: row.expiry,
-            is_deleted
+            is_deleted,
         };
         files.push(file);
     }
@@ -421,7 +424,7 @@ pub async fn get_file_metrics(sqlconn: &Pool<Sqlite>) -> Option<Vec<FileMetric>>
                 filesize: row.filesize,
                 views: row.views.unwrap(),
                 expiry: row.expiry,
-                is_deleted: false
+                is_deleted: false,
             };
             // Then add the struct to the Vec
             filevec.push(file);
diff --git a/src/engine.rs b/src/engine.rs
index ebdf4435fc13027f909ba2bb6735dd1bd21c374b..dcdfc28dd622ab763f17d204b3c37651847fdc46 100644
--- a/src/engine.rs
+++ b/src/engine.rs
@@ -37,8 +37,8 @@ where
 // This should check if the adminkey exists for another file, and regenerate if it does.
 pub async fn generate_adminkey(sqlconn: &Pool<Sqlite>) -> String {
     let adminkey_size: usize = CONFIG
-        .get_int("operations.adminkey_size")
-        .expect("Couldn't find 'adminkey_size' in config. :(")
+        .operations
+        .adminkey_size
         .try_into()
         .expect("Problem with converting adminkey_size to usize");
     let adminkey = nanoid!(adminkey_size);
@@ -54,9 +54,7 @@ pub async fn calculate_expiry<S>(sqlconn: &Pool<Sqlite>, filename: S, filesize:
 where
     S: AsRef<str>,
 {
-    let engine_mode: i64 = CONFIG
-        .get_int("operations.engine_mode")
-        .expect("Couldn't find 'engine_mode' in config. :(");
+    let engine_mode: i64 = CONFIG.operations.engine_mode;
 
     let expiry = match engine_mode {
         1 => engine_1(sqlconn, filename.as_ref()).await,
@@ -87,8 +85,8 @@ where
 {
     // Read the file expiry settings from the config
     let file_expiry_min: i32 = CONFIG
-        .get_int("operations.file_expiry_min")
-        .expect("Couldn't find 'file_expiry_min' in config. :(")
+        .operations
+        .file_expiry_min
         .try_into()
         .expect("The file_expiry_min is wayyyy to big.");
 
@@ -115,15 +113,9 @@ async fn engine_2(filesize: i32) -> i32 {
     // audron REVIEW: also, probably make that engine match use enums and give them descriptive names
 
     // Load settings from config
-    let file_expiry_min: f64 = CONFIG
-        .get_float("operations.file_expiry_min")
-        .expect("Couldn't find 'file_expiry_min' in config. :(");
-    let file_expiry_max: f64 = CONFIG
-        .get_float("operations.file_expiry_max")
-        .expect("Couldn't find 'file_expiry_min' in config. :(");
-    let max_filesize: f64 = CONFIG
-        .get_float("operations.max_filesize")
-        .expect("Couldn't find 'max_filesize' in config. :(");
+    let file_expiry_min: f64 = CONFIG.operations.file_expiry_min.into();
+    let file_expiry_max: f64 = CONFIG.operations.file_expiry_max.into();
+    let max_filesize: f64 = CONFIG.operations.max_filesize as f64;
 
     let time = SystemTime::now()
         .duration_since(SystemTime::UNIX_EPOCH)
diff --git a/src/handlers/delete_file.rs b/src/handlers/delete_file.rs
index 3acb1c737b45cb1482dfce171a6685d9912ac3b9..2679a81c8f9baa0248aad5f6f349cc2666268036 100644
--- a/src/handlers/delete_file.rs
+++ b/src/handlers/delete_file.rs
@@ -68,7 +68,7 @@ pub async fn delete_file(req: &mut Request, res: &mut Response) {
                 };
                 render_template(res, &headers, "error.html", template, StatusCode::OK).await
             } else {
-                res.set_status_code(StatusCode::OK);
+                res.status_code(StatusCode::OK);
                 res.render(Text::Json(r#"{"deletion": "success"}"#));
             }
         }
@@ -94,7 +94,7 @@ pub async fn delete_file(req: &mut Request, res: &mut Response) {
                 )
                 .await
             } else {
-                res.set_status_code(StatusCode::UNAUTHORIZED);
+                res.status_code(StatusCode::UNAUTHORIZED);
                 res.render(Text::Json(r#"{"error": "InvalidAdminKey"}"#));
             }
         }
diff --git a/src/handlers/index.rs b/src/handlers/index.rs
index dfb909b6760f10c11a7ea87572457d1d3f6c3d53..7d86d2242ff805ead752844c9e3509b62024d5fa 100644
--- a/src/handlers/index.rs
+++ b/src/handlers/index.rs
@@ -23,12 +23,5 @@ pub async fn index(req: &mut Request, res: &mut Response) {
         ),
         ..Default::default()
     };
-    render_template(
-        res,
-        headers,
-        "upload.html",
-        template,
-        StatusCode::OK,
-    )
-    .await
+    render_template(res, headers, "upload.html", template, StatusCode::OK).await
 }
diff --git a/src/handlers/list_files.rs b/src/handlers/list_files.rs
index e964a313a7a6c232d5b7d7f3c206d3a4859cde17..f3de33b5ccd4b1f8d8181daf9e4906b037e09c56 100644
--- a/src/handlers/list_files.rs
+++ b/src/handlers/list_files.rs
@@ -1,6 +1,13 @@
-use salvo::{handler, Request, Response, hyper::header::HOST, prelude::StatusCode};
+use salvo::{handler, hyper::header::HOST, prelude::StatusCode, Request, Response};
 
-use crate::{db, SQLITE, handlers::{TemplateStruct, render_template, convert_file_size, convert_unix_timestamp, count_file_metrics}};
+use crate::{
+    db,
+    handlers::{
+        convert_file_size, convert_unix_timestamp, count_file_metrics, render_template,
+        TemplateStruct,
+    },
+    SQLITE,
+};
 
 use super::guess_ip;
 
@@ -14,7 +21,7 @@ pub async fn list_files(req: &mut Request, res: &mut Response) {
 
     // Get the IP of the person viewing, so we can show their files
     let headers = req.headers();
-    let remote_addr = &req.remote_addr().unwrap().clone();
+    let remote_addr = &req.remote_addr().clone();
     let ip = guess_ip(headers, remote_addr);
 
     tracing::debug!("list_files(remote_addr, ip): {:?}, {:?}", remote_addr, ip);
@@ -77,12 +84,15 @@ pub async fn list_files(req: &mut Request, res: &mut Response) {
             render_template(res, headers, template_filename, template, status_code).await;
         }
     }
-    
+
     // Close the table when all files are 'rendered'
     html.push_str("</table>");
 
-    // Log this to the server console  
-    tracing::info!("New Request: /my_files ({} Files)", count_file_metrics(&files) );
+    // Log this to the server console
+    tracing::info!(
+        "New Request: /my_files ({} Files)",
+        count_file_metrics(&files)
+    );
 
     let template_filename = "my_files.html";
     let template = TemplateStruct {
diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs
index eca8f9423532f8c1c79908a18cd8efb866e3b085..4a95b8dc6c3d97cfadb53bd14626ccd9cb53013f 100644
--- a/src/handlers/mod.rs
+++ b/src/handlers/mod.rs
@@ -1,18 +1,22 @@
-use std::path::PathBuf;
+use std::{path::PathBuf, time::Duration};
 
+use chrono::{DateTime, Utc};
+use chrono_humanize::Humanize;
 use ramhorns::{Content, Ramhorns};
 use salvo::{
-    addr::SocketAddr,
+    conn::SocketAddr,
     hyper::{header::HOST, HeaderMap},
     prelude::StatusCode,
     writer::Text,
     Response,
 };
-use chrono::{DateTime, Utc};
-use chrono_humanize::Humanize;
 use sqlx::Error;
+use tokio::{task, time};
 
-use crate::{CONFIG, db::FileMetric};
+use crate::{
+    db::{self, FileMetric},
+    engine, CONFIG, COOKIE, SQLITE,
+};
 
 // Submodules for each request handler
 pub mod delete_file;
@@ -132,10 +136,13 @@ pub async fn render_template(
     };
 
     // Tell the engine to render the template assigned above
-    let rendered = tpls.get(template_filename).expect("Couldn't find the template filename").render(&template);
+    let rendered = tpls
+        .get(template_filename)
+        .expect("Couldn't find the template filename")
+        .render(&template);
 
     // Set the status code and render the completed page
-    res.set_status_code(status_code);
+    res.status_code(status_code);
     res.render(Text::Html(rendered));
 }
 
@@ -146,9 +153,7 @@ where
     S: AsRef<str>,
 {
     // Load the banned files from the config
-    let banned = CONFIG
-        .get_array("operations.banned_mimetype")
-        .expect("Couldn't find 'banned_mimetype' in config. :(");
+    let banned = &CONFIG.operations.banned_mimetype;
 
     // Convert the provided mimetype to lowercase for case-insensitive comparison
     let lowercase_mimetype = mimetype.as_ref().to_lowercase();
@@ -157,11 +162,7 @@ where
     let lowercase_banned: Vec<String> = banned
         .iter()
         .map(|mime| {
-            let mime_str = mime
-                .clone()
-                .into_string()
-                .expect("Invalid banned mimetype in config")
-                .to_lowercase();
+            let mime_str = mime.clone().to_lowercase();
             tracing::debug!("Banned mimetype: {}", mime_str);
             mime_str
         })
@@ -172,7 +173,6 @@ where
     lowercase_banned.contains(&lowercase_mimetype)
 }
 
-
 /// Convert the filesize to a human readable number
 fn convert_file_size(file_size: i64) -> String {
     let units = ["B", "KB", "MB", "GB", "TB"];
@@ -207,4 +207,58 @@ fn count_file_metrics(file_metrics: &Result<Vec<FileMetric>, Error>) -> usize {
         Ok(metrics) => metrics.len(),
         Err(_) => 0,
     }
-}
\ No newline at end of file
+}
+
+/// Guess the mimetype
+/// This uses the magic library, which seems to be the most accurate out of the ones I've seen.
+/// As the name suggests, this is magic. I have no idea HOW it works, but it should.
+/// This doesn't need the full file loaded into memory, so it loads 2048 bytes.
+fn detect_mime_type(file_data: &[u8]) -> Result<String, magic::MagicError> {
+    COOKIE.with(|cookie| {
+        let result = cookie.buffer(file_data)?;
+        Ok(result)
+    })
+}
+
+// This spawns a tokio task to run a interval timer forever.
+// the interval timer runs every 'period' seconds.
+pub fn cleaner_thread(period: i32) {
+    let _forever = task::spawn(async move {
+        let mut interval = time::interval(Duration::from_secs(period.try_into().unwrap()));
+        let sqlconn = SQLITE.get().unwrap();
+        loop {
+            // Wait for the next interval
+            interval.tick().await;
+            // Get a vec of files that will expire this loop.
+            // Also I'm sorta just realising how annoying it is to pass sqlconn through like 4 functions deep just to do something.
+            let old_files_result = db::get_old_files(sqlconn).await;
+
+            match old_files_result {
+                Ok(file_list) => {
+                    tracing::info!("Running Cleaner");
+                    for file in file_list {
+                        // Delete the file from the database
+                        db::delete_file(sqlconn, &file).await.unwrap_or_else(|err| {
+                            tracing::error!(
+                                "Failed to delete file from database: {}, error: {:?}",
+                                &file,
+                                err
+                            );
+                            0
+                        });
+                        // Delete the file from the filesystem
+                        engine::delete_file(&file).await.unwrap_or_else(|err| {
+                            tracing::error!("Failed to delete file from database: {:?}", err);
+                        });
+                    }
+                    tracing::info!("Cleaner finished");
+                }
+                Err(err) => {
+                    tracing::error!("Error getting files to expire: {}", err);
+                    // Return a empty Vec so it doesn't delete anything
+                    return Vec::<String>::new();
+                }
+            }
+        }
+    });
+}
diff --git a/src/handlers/mod_tests.rs b/src/handlers/mod_tests.rs
index d14bf47682a0f8a3469533d8e9a78358d9fb6895..f2f57bfd3a730333ff080d1b67f4bf7f75de1218 100644
--- a/src/handlers/mod_tests.rs
+++ b/src/handlers/mod_tests.rs
@@ -1,8 +1,7 @@
 #[cfg(test)]
 mod tests {
-    use crate::handlers::{guess_ip, is_mimetype_banned};
-    use config::Config;
-    use salvo::addr::SocketAddr as SalvoSocketAddr;
+    use crate::handlers::{detect_mime_type, guess_ip, is_mimetype_banned};
+    use salvo::conn::SocketAddr as SalvoSocketAddr;
     use salvo::hyper::HeaderMap;
     use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
 
@@ -102,4 +101,181 @@ mod tests {
         let result = is_mimetype_banned("aUdIo/MP4").await;
         assert!(!result);
     }
+
+    #[tokio::test]
+    async fn test_detect_mime_type() {
+        // Test case 1: Valid file data
+        let file_data = b"This is a test file";
+        let result = detect_mime_type(file_data);
+        println!("Test 1: Valid file data: {:?}", result);
+        assert!(result.is_ok());
+        assert_eq!(result.unwrap(), "text/plain");
+
+        // Test case 2: Empty file data
+        let file_data = b"";
+        let result = detect_mime_type(file_data);
+        println!("Test 2: Empty file data Result: {:?}", result);
+        assert!(result.is_ok());
+        assert_eq!(result.unwrap(), "application/x-empty");
+
+        // Test case 4: putty.exe
+        let file_data: &[u8] = &[
+            // Putty.exe trimmed at 2048
+            // This is stupid, and probably not needed for a test lol.
+            0x4D, 0x5A, 0x78, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x0E, 0x1F, 0xBA, 0x0E, 0x00, 0xB4,
+            0x09, 0xCD, 0x21, 0xB8, 0x01, 0x4C, 0xCD, 0x21, 0x54, 0x68, 0x69, 0x73, 0x20, 0x70,
+            0x72, 0x6F, 0x67, 0x72, 0x61, 0x6D, 0x20, 0x63, 0x61, 0x6E, 0x6E, 0x6F, 0x74, 0x20,
+            0x62, 0x65, 0x20, 0x72, 0x75, 0x6E, 0x20, 0x69, 0x6E, 0x20, 0x44, 0x4F, 0x53, 0x20,
+            0x6D, 0x6F, 0x64, 0x65, 0x2E, 0x24, 0x00, 0x00, 0x50, 0x45, 0x00, 0x00, 0x64, 0x86,
+            0x0A, 0x00, 0x91, 0x10, 0x5C, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0xF0, 0x00, 0x22, 0x00, 0x0B, 0x02, 0x0E, 0x00, 0x00, 0x5A, 0x0E, 0x00, 0x00, 0x70,
+            0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x88, 0x0B, 0x00, 0x00, 0x10, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02,
+            0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x19, 0x00, 0x00, 0x04, 0x00, 0x00, 0x44, 0xA8,
+            0x19, 0x00, 0x02, 0x00, 0x60, 0x81, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x11,
+            0x12, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x13, 0x00, 0x58, 0x9F, 0x05, 0x00,
+            0x00, 0xD0, 0x12, 0x00, 0x78, 0x6C, 0x00, 0x00, 0x00, 0xCE, 0x18, 0x00, 0x28, 0x57,
+            0x00, 0x00, 0x00, 0x40, 0x19, 0x00, 0xA8, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0E, 0x10, 0x00, 0x28, 0x00, 0x00, 0x00,
+            0xE0, 0xA6, 0x0F, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x28, 0x1D, 0x12, 0x00, 0xE0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2E, 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x00,
+            0x66, 0x59, 0x0E, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x5A, 0x0E, 0x00, 0x00, 0x04,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x20, 0x00, 0x00, 0x60, 0x2E, 0x72, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0xBC, 0xFF,
+            0x03, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x5E, 0x0E, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
+            0x00, 0x40, 0x2E, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x9C, 0x55, 0x00, 0x00,
+            0x00, 0x70, 0x12, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x5E, 0x12, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0xC0,
+            0x2E, 0x70, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x78, 0x6C, 0x00, 0x00, 0x00, 0xD0,
+            0x12, 0x00, 0x00, 0x6E, 0x00, 0x00, 0x00, 0x6E, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x2E, 0x30,
+            0x30, 0x63, 0x66, 0x67, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x40, 0x13, 0x00,
+            0x00, 0x02, 0x00, 0x00, 0x00, 0xDC, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x2E, 0x67, 0x78, 0x66,
+            0x67, 0x00, 0x00, 0x00, 0x60, 0x2A, 0x00, 0x00, 0x00, 0x50, 0x13, 0x00, 0x00, 0x2C,
+            0x00, 0x00, 0x00, 0xDE, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x2E, 0x74, 0x6C, 0x73, 0x00, 0x00,
+            0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x80, 0x13, 0x00, 0x00, 0x02, 0x00, 0x00,
+            0x00, 0x0A, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x40, 0x00, 0x00, 0xC0, 0x5F, 0x52, 0x44, 0x41, 0x54, 0x41, 0x00, 0x00,
+            0x5C, 0x01, 0x00, 0x00, 0x00, 0x90, 0x13, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0C,
+            0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x40, 0x00, 0x00, 0x40, 0x2E, 0x72, 0x73, 0x72, 0x63, 0x00, 0x00, 0x00, 0x58, 0x9F,
+            0x05, 0x00, 0x00, 0xA0, 0x13, 0x00, 0x00, 0xA0, 0x05, 0x00, 0x00, 0x0E, 0x13, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
+            0x00, 0x40, 0x2E, 0x72, 0x65, 0x6C, 0x6F, 0x63, 0x00, 0x00, 0xA8, 0x1E, 0x00, 0x00,
+            0x00, 0x40, 0x19, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0xAE, 0x18, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x42,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x56, 0x57, 0x53, 0x48, 0x83, 0xEC, 0x40, 0x48, 0x89, 0xD6, 0x48, 0x89,
+            0xCF, 0x4C, 0x89, 0x44, 0x24, 0x70, 0x4C, 0x89, 0x4C, 0x24, 0x78, 0x48, 0x8B, 0x05,
+            0x32, 0x60, 0x12, 0x00, 0x48, 0x31, 0xE0, 0x48, 0x89, 0x44, 0x24, 0x38, 0x48, 0x8D,
+            0x5C, 0x24, 0x70, 0x48, 0x89, 0x5C, 0x24, 0x30, 0xE8, 0xBB, 0x61, 0x00, 0x00, 0x48,
+            0x8B, 0x08, 0x48, 0x83, 0xC9, 0x01, 0x48, 0x89, 0x5C, 0x24, 0x28, 0x48, 0xC7, 0x44,
+            0x24, 0x20, 0x00, 0x00, 0x00, 0x00, 0x48, 0x89, 0xFA, 0x49, 0xC7, 0xC0, 0xFF, 0xFF,
+            0xFF, 0xFF, 0x49, 0x89, 0xF1, 0xE8, 0x9C, 0x98, 0x0B, 0x00, 0x89, 0xC6, 0x85, 0xC0,
+            0xB8, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x48, 0xF0, 0x48, 0x8B, 0x4C, 0x24, 0x38, 0x48,
+            0x31, 0xE1, 0xE8, 0x8B, 0x72, 0x0B, 0x00, 0x89, 0xF0, 0x48, 0x83, 0xC4, 0x40, 0x5B,
+            0x5F, 0x5E, 0xC3, 0xCC, 0x56, 0x48, 0x83, 0xEC, 0x70, 0x48, 0x8B, 0x05, 0xC4, 0x5F,
+            0x12, 0x00, 0x48, 0x31, 0xE0, 0x48, 0x89, 0x44, 0x24, 0x68, 0x48, 0x8B, 0x35, 0x6D,
+            0x6E, 0x12, 0x00, 0x48, 0x85, 0xF6, 0x74, 0x20, 0x48, 0x83, 0x3D, 0x68, 0x6E, 0x12,
+            0x00, 0x00, 0x74, 0x3A, 0x48, 0x8B, 0x4C, 0x24, 0x68, 0x48, 0x31, 0xE1, 0xE8, 0x49,
+            0x72, 0x0B, 0x00, 0x48, 0x89, 0xF0, 0x48, 0x83, 0xC4, 0x70, 0x5E, 0xC3, 0x4C, 0x8B,
+            0x05, 0x49, 0x61, 0x0E, 0x00, 0x31, 0xC9, 0x31, 0xD2, 0xE8, 0x60, 0x0F, 0x04, 0x00,
+            0x48, 0x89, 0xC6, 0x48, 0x89, 0x05, 0x2E, 0x6E, 0x12, 0x00, 0x48, 0x83, 0x3D, 0x2E,
+            0x6E, 0x12, 0x00, 0x00, 0x75, 0xC6, 0xC7, 0x44, 0x24, 0x20, 0x00, 0x00, 0x00, 0x00,
+            0x48, 0x8D, 0x05, 0x6D, 0x00, 0x00, 0x00, 0x48, 0x89, 0x44, 0x24, 0x28, 0x48, 0xC7,
+            0x44, 0x24, 0x30, 0x00, 0x00, 0x00, 0x00, 0x48, 0x8B, 0x0D, 0x10, 0x6E, 0x12, 0x00,
+            0x48, 0x89, 0x4C, 0x24, 0x38, 0xBA, 0xC8, 0x00, 0x00, 0x00, 0xFF, 0x15, 0x20, 0x10,
+            0x12, 0x00, 0x48, 0x89, 0x44, 0x24, 0x40, 0xBA, 0x01, 0x7F, 0x00, 0x00, 0x31, 0xC9,
+            0xFF, 0x15, 0x06, 0x10, 0x12, 0x00, 0x48, 0x89, 0x44, 0x24, 0x48, 0x0F, 0x57, 0xC0,
+            0x0F, 0x11, 0x44, 0x24, 0x50, 0x48, 0x8B, 0x05, 0xCA, 0x6D, 0x12, 0x00, 0x48, 0x89,
+            0x44, 0x24, 0x60, 0x48, 0x8D, 0x4C, 0x24, 0x20, 0xFF, 0x15, 0x62, 0x10, 0x12, 0x00,
+            0x48, 0x8B, 0x35, 0xB3, 0x6D, 0x12, 0x00, 0xE9, 0x50, 0xFF, 0xFF, 0xFF, 0xCC, 0xCC,
+            0xCC, 0xCC, 0xCC, 0xCC, 0x41, 0x57, 0x41, 0x56, 0x41, 0x55, 0x41, 0x54, 0x56, 0x57,
+            0x55, 0x53, 0x48, 0x81, 0xEC, 0x18, 0x09, 0x00, 0x00, 0x4D, 0x89, 0xCD, 0x4D, 0x89,
+            0xC7, 0x89, 0xD6, 0x49, 0x89, 0xCE, 0x48, 0x8B, 0x05, 0xCB, 0x5E, 0x12, 0x00, 0x48,
+            0x31, 0xE0, 0x48, 0x89, 0x84, 0x24, 0x10, 0x09, 0x00, 0x00, 0x81, 0xFA, 0xFF, 0x01,
+            0x00, 0x00, 0x0F, 0x8F, 0x8A, 0x00, 0x00, 0x00, 0x8D, 0x86, 0x60, 0xFF, 0xFF, 0xFF,
+            0x83, 0xF8, 0x77, 0x0F, 0x87, 0xC1, 0x01, 0x00, 0x00, 0x48, 0x8D, 0x0D, 0xC2, 0x39,
+            0x00, 0x00, 0x48, 0x63, 0x04, 0x81, 0x48, 0x01, 0xC8, 0xFF, 0xE0, 0xB9, 0x03, 0x00,
+            0x00, 0x00, 0x44, 0x89, 0xEA, 0xE8, 0x08, 0xEE, 0x02, 0x00, 0x4C, 0x89, 0xF8, 0x48,
+            0x83, 0xE0, 0xFD, 0x48, 0x3D, 0xE5, 0x00, 0x00, 0x00, 0x0F, 0x85, 0xDF, 0x02, 0x00,
+            0x00, 0x81, 0xFE, 0x00, 0x01, 0x00, 0x00, 0x0F, 0x85, 0x8C, 0x24, 0x00, 0x00, 0x4C,
+            0x89, 0xB4, 0x24, 0x10, 0x01, 0x00, 0x00, 0xC7, 0x84, 0x24, 0x18, 0x01, 0x00, 0x00,
+            0x00, 0x01, 0x00, 0x00, 0x4C, 0x89, 0xBC, 0x24, 0x20, 0x01, 0x00, 0x00, 0x41, 0x81,
+            0xE5, 0xFF, 0xDF, 0x00, 0x00, 0x4C, 0x89, 0xAC, 0x24, 0x28, 0x01, 0x00, 0x00, 0x48,
+            0x8D, 0x8C, 0x24, 0x10, 0x01, 0x00, 0x00, 0xFF, 0x15, 0x89, 0x10, 0x12, 0x00, 0x31,
+            0xF6, 0xE9, 0x61, 0x24, 0x00, 0x00, 0x81, 0xFE, 0xDF, 0x02, 0x00, 0x00, 0x0F, 0x8F,
+            0x91, 0x01, 0x00, 0x00, 0x8D, 0x86, 0x00, 0xFE, 0xFF, 0xFF, 0x83, 0xF8, 0x32, 0x0F,
+            0x87, 0xBF, 0x03, 0x00, 0x00, 0x48, 0x8D, 0x0D, 0x0C, 0x3B, 0x00, 0x00, 0x48, 0x63,
+            0x04, 0x81, 0x48, 0x01, 0xC8, 0xFF, 0xE0, 0x4C, 0x39, 0x3D, 0x88, 0x80, 0x12, 0x00,
+            0x75, 0x15, 0x4C, 0x39, 0x2D, 0x87, 0x80, 0x12, 0x00, 0x75, 0x0C, 0x81, 0x3D, 0x57,
+            0x80, 0x12, 0x00, 0x00, 0x02, 0x00, 0x00, 0x74, 0x1F, 0xB1, 0x01, 0xE8, 0x5A, 0x5E,
+            0x00, 0x00, 0x4C, 0x89, 0x3D, 0x63, 0x80, 0x12, 0x00, 0x4C, 0x89, 0x2D, 0x64, 0x80,
+            0x12, 0x00, 0xC7, 0x05, 0x36, 0x80, 0x12, 0x00, 0x00, 0x02, 0x00, 0x00, 0xB9, 0x05,
+            0x00, 0x00, 0x00, 0x44, 0x89, 0xEA, 0xE8, 0x35, 0xED, 0x02, 0x00, 0x41, 0xF6, 0xC7,
+            0x13, 0x0F, 0x84, 0x1F, 0x1E, 0x00, 0x00, 0xFF, 0x15, 0x5D, 0x0D, 0x12, 0x00, 0x4C,
+            0x39, 0xF0, 0x0F, 0x85, 0x10, 0x1E, 0x00, 0x00, 0x31, 0xC0, 0x41, 0xF6, 0xC7, 0x10,
+            0x0F, 0x94, 0xC0, 0x83, 0xC8, 0x02, 0x41, 0xF6, 0xC7, 0x01, 0xBE, 0x01, 0x00, 0x00,
+            0x00, 0x0F, 0x44, 0xF0, 0xE8, 0x6F, 0xB3, 0x00, 0x00, 0x41, 0x89, 0xC6, 0x44, 0x89,
+            0xFF, 0x83, 0xE7, 0x08, 0xC1, 0xEF, 0x03, 0x41, 0x83, 0xE7, 0x04, 0x41, 0xC1, 0xEF,
+            0x02, 0x44, 0x89, 0xE9, 0xC1, 0xF9, 0x10, 0x8B, 0x2D, 0x4F, 0x77, 0x12, 0x00, 0x89,
+            0xC8, 0x29, 0xE8, 0x83, 0xC0, 0x01, 0x45, 0x85, 0xED, 0x0F, 0x49, 0xC1, 0x2B, 0x05,
+            0x94, 0x77, 0x12, 0x00, 0x99, 0xF7, 0xFD, 0x89, 0xC5, 0x44, 0x89, 0xE9, 0xC1, 0xE1,
+            0x10, 0x41, 0x0F, 0xBF, 0xD5, 0x8B, 0x1D, 0x23, 0x77, 0x12, 0x00, 0x89, 0xD0, 0x29,
+            0xD8, 0x83, 0xC0, 0x01, 0x85, 0xC9, 0x0F, 0x49, 0xC2, 0x2B, 0x05, 0x71, 0x77, 0x12,
+            0x00, 0x99, 0xF7, 0xFB, 0x89, 0xC3, 0x89, 0xF1, 0xE8, 0x69, 0xB3, 0x00, 0x00, 0x48,
+            0x8B, 0x0D, 0x4A, 0x77, 0x12, 0x00, 0x44, 0x88, 0x74, 0x24, 0x40, 0x40, 0x88, 0x7C,
+            0x24, 0x38, 0x44, 0x88, 0x7C, 0x24, 0x30, 0x89, 0x6C, 0x24, 0x28, 0x89, 0x5C, 0x24,
+            0x20, 0x89, 0xF2, 0x41, 0x89, 0xC0, 0x41, 0xB9, 0x04, 0x00, 0x00, 0x00, 0xE8, 0x7B,
+            0x25, 0x01, 0x00, 0x31, 0xF6, 0xE9, 0x1B, 0x23, 0x00, 0x00, 0x8D, 0x46, 0xFF, 0x83,
+            0xF8, 0x50, 0x0F, 0x87, 0x42, 0x0B, 0x00, 0x00, 0x48, 0x8D, 0x0D, 0xB1, 0x36, 0x00,
+            0x00, 0x48, 0x63, 0x04, 0x81, 0x48, 0x01, 0xC8, 0xFF, 0xE0, 0x48, 0x8B, 0x0D, 0x99,
+            0x6B, 0x12, 0x00, 0xBA, 0x89, 0x00, 0x00, 0x00, 0xE8, 0x37, 0xF6, 0x03, 0x00, 0x80,
+            0x3D, 0x90, 0x5C, 0x12, 0x00, 0x00, 0x75, 0x0B, 0xB9, 0x01, 0x00, 0x00, 0x00, 0xFF,
+            0x15, 0xD3, 0x0E, 0x12, 0x00, 0xC6, 0x05, 0x7C, 0x5C, 0x12, 0x00, 0x01, 0x31, 0xF6,
+            0x31, 0xC9, 0xFF, 0x15, 0xE2, 0x0D, 0x12, 0x00, 0xE9, 0xC4, 0x22, 0x00, 0x00, 0x81,
+            0xFE, 0x10, 0x03, 0x00, 0x00, 0x7F, 0x6B, 0x81, 0xFE, 0xE0, 0x02, 0x00, 0x00, 0x0F,
+            0x84, 0xF5, 0x01, 0x00, 0x00, 0x81, 0xFE, 0x07, 0x03, 0x00, 0x00, 0x0F, 0x84, 0xC1,
+            0x01, 0x00, 0x00, 0x81, 0xFE, 0x0F, 0x03, 0x00, 0x00, 0x0F, 0x85, 0xCB, 0x0A, 0x00,
+            0x00, 0x48, 0x83, 0x3D, 0x09, 0x77, 0x12, 0x00, 0x00, 0x0F, 0x84, 0xC7, 0x1C, 0x00,
+            0x00, 0xE8, 0x3E, 0x89,
+        ];
+        let result = detect_mime_type(file_data);
+        println!("Test case 3: putty.exe: {:?}", result);
+        assert!(result.is_ok());
+        assert_eq!(
+            result.unwrap(),
+            "application/vnd.microsoft.portable-executable"
+        );
+    }
 }
diff --git a/src/handlers/serve_file.rs b/src/handlers/serve_file.rs
index dbf1542451b8ee4aa07661693670b1ac1af70a23..1500fdafe95ed70f7ed5b214e5889466fd7b95f1 100644
--- a/src/handlers/serve_file.rs
+++ b/src/handlers/serve_file.rs
@@ -55,7 +55,7 @@ pub async fn serve_file(req: &mut Request, res: &mut Response) {
                 let status_code = StatusCode::NOT_FOUND;
                 render_template(res, &headers, template_filename, template, status_code).await;
             } else {
-                res.set_status_code(StatusCode::NOT_FOUND);
+                res.status_code(StatusCode::NOT_FOUND);
                 res.render(Text::Json(r#"{"error": "FileNotFound"}"#));
             }
 
@@ -81,7 +81,7 @@ pub async fn serve_file(req: &mut Request, res: &mut Response) {
                 let status_code = StatusCode::INTERNAL_SERVER_ERROR;
                 render_template(res, &headers, template_filename, template, status_code).await;
             } else {
-                res.set_status_code(StatusCode::UNAUTHORIZED);
+                res.status_code(StatusCode::UNAUTHORIZED);
                 res.render(Text::Json(r#"{"error": "InternalServerError"}"#));
             }
         }
@@ -91,9 +91,7 @@ pub async fn serve_file(req: &mut Request, res: &mut Response) {
             tracing::info!("New File View: {:?}", &filename.to_string());
 
             // Read the list of unsafe mimetypes from the config
-            let mime_unsafe = CONFIG
-                .get_array("operations.unsafe_mimetype")
-                .expect("Couldn't find 'unsafe_mimetype' in config. :(");
+            let mime_unsafe = &CONFIG.operations.unsafe_mimetype;
 
             // Get the mimetype of the file.
             let mut mimetype: String = db::get_mimetype(sqlconn, &filename).await.unwrap();
@@ -103,7 +101,7 @@ pub async fn serve_file(req: &mut Request, res: &mut Response) {
             // The predicate in this case is a closure that checks if the current mime type matches the unsafe mime type.
             if mime_unsafe
                 .iter() // Iterate over the collection
-                .any(|mime| mime.clone().into_string().unwrap() == mimetype.clone())
+                .any(|mime| mime.clone() == mimetype.clone())
             {
                 // Check if any of the unsafe mime types match the given mimetype
                 tracing::info!("Unsafe Extension Filtered: {:?}", mimetype);
@@ -137,9 +135,7 @@ pub async fn serve_file(req: &mut Request, res: &mut Response) {
             engine::calculate_expiry(sqlconn, filename.clone(), filesize).await;
 
             // Check if nginx sendfile is enabled, because we can skip this if it is.
-            let nginxsendfile = CONFIG
-                .get_bool("server.nginx_sendfile")
-                .expect("Couldn't find 'nginx_sendfile' in config. :(");
+            let nginxsendfile = CONFIG.server.nginx_sendfile;
 
             if nginxsendfile {
                 // Add the X-Accel-Redirect header, allowing for faster file serving.
@@ -154,7 +150,7 @@ pub async fn serve_file(req: &mut Request, res: &mut Response) {
                 tracing::debug!("response headers: {:?}", res.headers());
 
                 // https://github.com/salvo-rs/salvo/issues/233
-                res.set_status_code(StatusCode::OK);
+                res.status_code(StatusCode::OK);
             } else {
                 // If nginx sendfile is disabled, we need to render the file directly
 
@@ -170,7 +166,7 @@ pub async fn serve_file(req: &mut Request, res: &mut Response) {
                 // Go through all the headers and print them out, just to check for now!
                 tracing::debug!("response headers: {:?}", res.headers());
 
-                res.set_status_code(StatusCode::OK);
+                res.status_code(StatusCode::OK);
             }
         }
     };
diff --git a/src/handlers/serve_static.rs b/src/handlers/serve_static.rs
index decc20bbe998016a9b49c587be70084a80bc907d..7788144590617c743614de124d8a1f641adbcd8d 100644
--- a/src/handlers/serve_static.rs
+++ b/src/handlers/serve_static.rs
@@ -16,7 +16,7 @@ use crate::{db, handlers::TemplateStruct, SQLITE};
 #[handler]
 pub async fn serve_static(req: &mut Request, res: &mut Response) {
     let headers = &req.headers().clone();
-    let remote_addr = &req.remote_addr().unwrap().clone();
+    let remote_addr = &req.remote_addr().clone();
     let host = headers[HOST].to_str().unwrap_or("localhost:8282");
     let template_host_path = PathBuf::from("./templates/").join(host);
     let template_host_path_default = PathBuf::from("./templates/localhost:8282");
@@ -38,7 +38,7 @@ pub async fn serve_static(req: &mut Request, res: &mut Response) {
                 ..Default::default()
             };
             let rendered = tpls.get("services.html").unwrap().render(&template);
-            res.set_status_code(StatusCode::OK);
+            res.status_code(StatusCode::OK);
             res.render(Text::Html(rendered));
         }
         "/about" => {
@@ -52,7 +52,7 @@ pub async fn serve_static(req: &mut Request, res: &mut Response) {
                 ..Default::default()
             };
             let rendered = tpls.get("about.html").unwrap().render(&template);
-            res.set_status_code(StatusCode::OK);
+            res.status_code(StatusCode::OK);
             res.render(Text::Html(rendered));
         }
         "/faq" => {
@@ -66,7 +66,7 @@ pub async fn serve_static(req: &mut Request, res: &mut Response) {
                 ..Default::default()
             };
             let rendered = tpls.get("faq.html").unwrap().render(&template);
-            res.set_status_code(StatusCode::OK);
+            res.status_code(StatusCode::OK);
             res.render(Text::Html(rendered));
         }
         "/dmca" => {
@@ -81,7 +81,7 @@ pub async fn serve_static(req: &mut Request, res: &mut Response) {
                 ..Default::default()
             };
             let rendered = tpls.get("dmca.html").unwrap().render(&template);
-            res.set_status_code(StatusCode::OK);
+            res.status_code(StatusCode::OK);
             res.render(Text::Html(rendered));
         }
         "/welcome" => {
@@ -96,7 +96,7 @@ pub async fn serve_static(req: &mut Request, res: &mut Response) {
                 ..Default::default()
             };
             let rendered = tpls.get("welcome.html").unwrap().render(&template);
-            res.set_status_code(StatusCode::OK);
+            res.status_code(StatusCode::OK);
             res.render(Text::Html(rendered));
         }
         "/czb" => {
@@ -111,7 +111,7 @@ pub async fn serve_static(req: &mut Request, res: &mut Response) {
                 ..Default::default()
             };
             let rendered = tpls.get("czb.html").unwrap().render(&template);
-            res.set_status_code(StatusCode::OK);
+            res.status_code(StatusCode::OK);
             res.render(Text::Html(rendered));
         }
         "/qr" => {
@@ -138,7 +138,7 @@ pub async fn serve_static(req: &mut Request, res: &mut Response) {
                 ..Default::default()
             };
             let rendered = tpls.get("qr.html").unwrap().render(&template);
-            res.set_status_code(StatusCode::OK);
+            res.status_code(StatusCode::OK);
             res.render(Text::Html(rendered));
         }
         _ => {
diff --git a/src/handlers/upload.rs b/src/handlers/upload.rs
index 99d0cf95c57633f1125dfccd8d4153af15afa39c..c68a97909eac51c924da0c14f5e6a358adeaf4a8 100644
--- a/src/handlers/upload.rs
+++ b/src/handlers/upload.rs
@@ -1,7 +1,8 @@
 use chrono::{TimeZone, Utc};
 use salvo::{handler, hyper::header::HOST, prelude::StatusCode, writer::Text, Request, Response};
 use std::{
-    fs,
+    fs::{self, File},
+    io::Read,
     path::{Path, PathBuf},
     time::SystemTime,
 };
@@ -9,8 +10,8 @@ use std::{
 use super::guess_ip;
 use crate::{
     db, engine,
-    handlers::{is_mimetype_banned, render_template, TemplateStruct},
-    CONFIG, SQLITE, MAGIC,
+    handlers::{detect_mime_type, is_mimetype_banned, render_template, TemplateStruct},
+    CONFIG, SQLITE,
 };
 
 /// This file handles (heh) uploading files to the server.
@@ -20,7 +21,7 @@ pub async fn upload(req: &mut Request, res: &mut Response) {
     let sqlconn = SQLITE.get().unwrap();
     // Clone out the header and remote_addr so we can guess the ip later
     let headers = &req.headers().clone();
-    let remote_addr = &req.remote_addr().unwrap().clone();
+    let remote_addr = &req.remote_addr().clone();
     // Get the host header for nicely setting up the response.
     let host = headers[HOST].to_str().unwrap_or("localhost:8282");
     tracing::debug!("upload(req): {:?}", req);
@@ -45,16 +46,21 @@ pub async fn upload(req: &mut Request, res: &mut Response) {
     if let Some(file) = req.file("file").await {
         // Generate new filename.
         // Set up the filename length from the config
-        let length = CONFIG
-            .get_int("operations.filename_size")
-            .expect("Couldn't find 'filename_size' in config. :(") as usize;
+        let length = CONFIG.operations.filename_size as usize;
         let filename =
             engine::generate_filename(length, file.name().unwrap_or("file").to_string()).await;
 
-        // Guess the mimetype from the file.
-        let file_path = file.path();
-        let mimetype = tree_magic_mini::from_filepath(&file_path)
-                 .unwrap_or("text/plain");
+        // Get the temporary file
+        let mut mime_file = File::open(file.path()).expect("Error opening file");
+        let mut buffer = vec![0; 2048];
+
+        // Load up 2048 bytes (There wasn't a decent answer on how much or little I should read)
+        mime_file
+            .read_exact(&mut buffer)
+            .expect("Error reading file");
+
+        // Guess the mimetype
+        let mimetype: &str = &detect_mime_type(&buffer).unwrap_or("text/plain".to_string());
 
         tracing::debug!("upload(mimetype): {:?}", mimetype);
 
@@ -75,7 +81,7 @@ pub async fn upload(req: &mut Request, res: &mut Response) {
                 render_template(res, headers, template_filename, template, status_code).await;
             } else {
                 // Otherwise, render the error in json for the API.
-                res.set_status_code(StatusCode::FORBIDDEN);
+                res.status_code(StatusCode::FORBIDDEN);
                 res.render(Text::Json(r#"{"error": "BlockedFiletype"}"#));
             }
         } else {
@@ -111,7 +117,7 @@ pub async fn upload(req: &mut Request, res: &mut Response) {
                     let status_code = StatusCode::INTERNAL_SERVER_ERROR;
                     render_template(res, headers, template_filename, template, status_code).await;
                 } else {
-                    res.set_status_code(StatusCode::INTERNAL_SERVER_ERROR);
+                    res.status_code(StatusCode::INTERNAL_SERVER_ERROR);
                     res.render(Text::Json(r#"{"error": "InternalServerError"}"#));
                 }
             } else {
@@ -189,7 +195,7 @@ pub async fn upload(req: &mut Request, res: &mut Response) {
                     let status_code = StatusCode::OK;
                     render_template(res, headers, template_filename, template, status_code).await;
                 } else {
-                    res.set_status_code(StatusCode::OK);
+                    res.status_code(StatusCode::OK);
 
                     res.render(Text::Json(format!(
                         r#"{{"file": "{}", "url": "{}", "adminurl": "{}", "expiry": {}}}"#,
@@ -214,7 +220,7 @@ pub async fn upload(req: &mut Request, res: &mut Response) {
         let status_code = StatusCode::BAD_REQUEST;
         render_template(res, headers, template_filename, template, status_code).await;
     } else {
-        res.set_status_code(StatusCode::BAD_REQUEST);
+        res.status_code(StatusCode::BAD_REQUEST);
         res.render(Text::Json(r#"{"error": "BadRequest"}"#));
     };
 }
diff --git a/src/main.rs b/src/main.rs
index 6adefb68eb31b929ee6d772b966f2c2773c0c1ba..0e40896757d096ff3eeea44a81f8034824144d17 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,20 +1,23 @@
+use figment::providers::{Format, Toml};
+use figment::Figment;
+use magic::Cookie;
 use once_cell::sync::OnceCell;
 use salvo::prelude::*;
 use salvo::serve_static::{StaticDir, StaticFile};
 use sqlx::SqlitePool;
 
-use config::Config;
 use lazy_static::lazy_static;
 use std::fs::create_dir_all;
-use std::time::Duration;
-use tokio::{task, time};
 use tracing_subscriber::filter::EnvFilter;
 use tracing_subscriber::fmt;
 use tracing_subscriber::prelude::*;
 
+use crate::config::AppConfig;
 use crate::db::DatabaseType;
+use crate::handlers::cleaner_thread;
 
 // Import sub-modules.
+mod config;
 mod db;
 mod engine;
 
@@ -30,21 +33,40 @@ mod handlers;
 // Setup the global sqlite db
 static SQLITE: OnceCell<SqlitePool> = OnceCell::new();
 
+// Initialise the magic db
+// This is thread-local, so each thread will have it's own database loaded.
+// It's probably not the best way of doing it
+// and we could probably have a dedicated thread for mimetypes but idk i'm not that smart
+thread_local! {
+    static COOKIE: Cookie = {
+        let cookie = Cookie::open(magic::CookieFlags::MIME_TYPE).unwrap();
+        // Load the default database
+        cookie.load::<&str>(&[]).unwrap();
+        cookie
+    };
+}
+
 // Setup the config globally because I can't figure out how to pass it to functions I don't call directly.
 // This is evaluated at runtime, and not compilation. \o/
 lazy_static! {
-    pub static ref CONFIG: Config = Config::builder()
-        .add_source(config::File::with_name("config.toml"))
-        .build()
-        .unwrap();
+    pub static ref CONFIG: AppConfig = {
+        let config = Figment::new()
+            .merge(Toml::file("config.toml"))
+            .extract()
+            .unwrap_or_else(|error| {
+                eprintln!("Error loading configuration: {}", error);
+                std::process::exit(1);
+            });
+
+        tracing::debug!("full config: {:?}", config);
+        config
+    };
 }
 
 #[tokio::main]
 async fn main() {
     // Read log level from config
-    let log_config = CONFIG
-        .get_string("logging.level")
-        .expect("Couldn't find 'sql_backend' in config. :(");
+    let log_config = &CONFIG.logging.level;
 
     // Construct tracing_subscriber with the filter from config.
     tracing_subscriber::registry()
@@ -53,13 +75,9 @@ async fn main() {
         .init();
 
     // Determine what SQL engine we're running.
-    let sql_backend = CONFIG
-        .get_string("database.sql_backend")
-        .expect("Couldn't find 'sql_backend' in config. :(");
+    let sql_backend = &CONFIG.database.sql_backend;
 
-    let db_url = CONFIG
-        .get_string("database.url")
-        .expect("Couldn't find 'url' in config. :(");
+    let db_url = &CONFIG.database.url;
 
     // Match on the database type
     match DatabaseType::from_str(&sql_backend) {
@@ -94,15 +112,11 @@ async fn main() {
     };
 
     // Initialise the cleaner task
-    let interval = CONFIG
-        .get_int("operations.cleaner_interval")
-        .expect("Couldn't find 'cleaner_interval' in config. :(");
-    tracing::debug!("cleaner_interval: {}", interval);
-    cleaner_thread(
-        interval
-            .try_into()
-            .expect("Cleaner interval was too long to fit in a i32.... wow"),
+    tracing::info!(
+        "Starting cleaner thread every {} seconds",
+        CONFIG.operations.cleaner_interval
     );
+    cleaner_thread(CONFIG.operations.cleaner_interval);
 
     // Attempt to create the files directory
     create_dir_all("files").unwrap();
@@ -110,7 +124,6 @@ async fn main() {
     // Internal routing
     let router = Router::new()
         // Main / functions
-        .hoop(Logger)
         .get(handlers::index::index)
         .post(handlers::upload::upload)
         // Static Pages
@@ -123,10 +136,9 @@ async fn main() {
         .push(Router::with_path("/welcome").get(handlers::serve_static::serve_static))
         .push(Router::with_path("/metrics").get(handlers::serve_metrics::serve_metrics))
         .push(Router::with_path("/favicon.ico").get(StaticFile::new("static/favicon32.webp")))
+        .push(Router::with_path("/robots.txt").get(StaticFile::new("static/robots.txt")))
         // Static File Serving
-        .push(
-            Router::with_path("static/<**path>").get(StaticDir::new("static/").with_listing(true)),
-        )
+        .push(Router::with_path("static/<**path>").get(StaticDir::new("static/").listing(true)))
         // Deletion API
         .push(
             Router::with_path("/delete/<adminkey>")
@@ -144,62 +156,21 @@ async fn main() {
         .push(Router::with_path("<file>").get(handlers::serve_file::serve_file));
 
     // Read environment variables for host and port
-    let host = CONFIG
-        .get_string("server.host")
-        .expect("Couldn't find 'host' in config. :(");
-    let port = CONFIG
-        .get_int("server.port")
-        .expect("Couldn't find 'port' in config. :(");
+    let host = &CONFIG.server.host;
+    let port = CONFIG.server.port;
     let server_url = format!("{}:{}", host, port);
     tracing::info!("Listening on http://{}", server_url);
-    Server::new(TcpListener::bind(&server_url))
-        .serve(router)
-        .await;
+    // TODO: Allow us to listen on a socket too?
+    // let acceptor = UnixListener::new("/tmp/salvo.sock").bind().await;
+    let acceptor = TcpListener::new(&server_url).bind().await;
+
+    Server::new(acceptor).serve(router).await;
 
     // Close SQLite before closing
     tracing::info!("Attempting to safely shut down Ephemeral.");
-    SQLITE.get().expect("Problem while safely closing the database :(").close().await;
-}
-
-// This spawns a tokio task to run a interval timer forever.
-// the interval timer runs every 'period' seconds.
-pub fn cleaner_thread(period: i32) {
-    let _forever = task::spawn(async move {
-        let mut interval = time::interval(Duration::from_secs(period.try_into().unwrap()));
-        let sqlconn = SQLITE.get().unwrap();
-        loop {
-            // Wait for the next interval
-            interval.tick().await;
-            // Get a vec of files that will expire this loop.
-            // Also I'm sorta just realising how annoying it is to pass sqlconn through like 4 functions deep just to do something.
-            let old_files_result = db::get_old_files(sqlconn).await;
-
-            match old_files_result {
-                Ok(file_list) => {
-                    tracing::info!("Running Cleaner");
-                    for file in file_list {
-                        // Delete the file from the database
-                        db::delete_file(sqlconn, &file).await.unwrap_or_else(|err| {
-                            tracing::error!(
-                                "Failed to delete file from database: {}, error: {:?}",
-                                &file,
-                                err
-                            );
-                            0
-                        });
-                        // Delete the file from the filesystem
-                        engine::delete_file(&file).await.unwrap_or_else(|err| {
-                            tracing::error!("Failed to delete file from database: {:?}", err);
-                        });
-                    }
-                    tracing::info!("Cleaner finished");
-                }
-                Err(err) => {
-                    tracing::error!("Error getting files to expire: {}", err);
-                    // Return a empty Vec so it doesn't delete anything
-                    return Vec::<String>::new();
-                }
-            }
-        }
-    });
+    SQLITE
+        .get()
+        .expect("Problem while safely closing the database :(")
+        .close()
+        .await;
 }
diff --git a/static/robots.txt b/static/robots.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391