commit 0c0a80720e2986c343d736b6b43b028afd2f7fdf
parent 3bd4e42fb01781dce454031402ed26e92dc055e4
Author: Daniel GarcĂa <dani-garcia@users.noreply.github.com>
Date: Mon, 10 Apr 2023 21:10:29 +0200
Merge pull request #3404 from BlackDex/websockets-via-rocket
WebSockets via Rocket's Upgrade connection
Diffstat:
M | Cargo.lock | | | 286 | +++++++++++++++++++++++++++++++++++++++++++++++++------------------------------ |
M | Cargo.toml | | | 17 | +++++++++++------ |
M | src/api/notifications.rs | | | 233 | ++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------- |
3 files changed, 344 insertions(+), 192 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
@@ -79,9 +79,9 @@ dependencies = [
[[package]]
name = "async-executor"
-version = "1.5.0"
+version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "17adb73da160dfb475c183343c8cccd80721ea5a605d3eb57125f0a7b7a92d0b"
+checksum = "6fa3dc5f2a8564f07759c008b9109dc0d39de92a88d5588b8a5036d286383afb"
dependencies = [
"async-lock",
"async-task",
@@ -137,9 +137,9 @@ dependencies = [
[[package]]
name = "async-process"
-version = "1.6.0"
+version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6381ead98388605d0d9ff86371043b5aa922a3905824244de40dc263a14fcba4"
+checksum = "7a9d28b1d97e08915212e2e45310d47854eafa69600756fc735fb788f75199c9"
dependencies = [
"async-io",
"async-lock",
@@ -148,9 +148,9 @@ dependencies = [
"cfg-if",
"event-listener",
"futures-lite",
- "libc",
+ "rustix",
"signal-hook",
- "windows-sys 0.42.0",
+ "windows-sys 0.48.0",
]
[[package]]
@@ -182,9 +182,9 @@ dependencies = [
[[package]]
name = "async-stream"
-version = "0.3.4"
+version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ad445822218ce64be7a341abfb0b1ea43b5c23aa83902542a4542e78309d8e5e"
+checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51"
dependencies = [
"async-stream-impl",
"futures-core",
@@ -193,13 +193,13 @@ dependencies = [
[[package]]
name = "async-stream-impl"
-version = "0.3.4"
+version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e4655ae1a7b0cdf149156f780c5bf3f1352bc53cbd9e0a361a7ef7b22947e965"
+checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193"
dependencies = [
"proc-macro2",
"quote",
- "syn 1.0.109",
+ "syn 2.0.13",
]
[[package]]
@@ -236,9 +236,9 @@ dependencies = [
[[package]]
name = "atomic-waker"
-version = "1.1.0"
+version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "debc29dde2e69f9e47506b525f639ed42300fc014a3e007832592448fa8e4599"
+checksum = "1181e1e0d1fce796a03db1ae795d67167da795f9cf4a39c37589e85ef57f26d3"
[[package]]
name = "autocfg"
@@ -278,9 +278,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
-version = "2.0.2"
+version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "487f1e0fcbe47deb8b0574e646def1c903389d95241dd1bbcc6ce4a715dfc0c1"
+checksum = "c70beb79cbb5ce9c4f8e20849978f34225931f665bb49efa6982875a4d5facb3"
[[package]]
name = "blake2"
@@ -302,9 +302,9 @@ dependencies = [
[[package]]
name = "blocking"
-version = "1.3.0"
+version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3c67b173a56acffd6d2326fb7ab938ba0b00a71480e14902b2591c87bc5741e8"
+checksum = "77231a1c8f801696fc0123ec6150ce92cffb8e164a02afb9c8ddee0e9b65ad65"
dependencies = [
"async-channel",
"async-lock",
@@ -312,6 +312,7 @@ dependencies = [
"atomic-waker",
"fastrand",
"futures-lite",
+ "log",
]
[[package]]
@@ -418,9 +419,9 @@ dependencies = [
[[package]]
name = "chrono-tz"
-version = "0.8.1"
+version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fa48fa079165080f11d7753fd0bc175b7d391f276b965fe4b55bfad67856e463"
+checksum = "cf9cc2b23599e6d7479755f3594285efb3f74a1bdca7a7374948bc831e23a552"
dependencies = [
"chrono",
"chrono-tz-build",
@@ -450,9 +451,9 @@ dependencies = [
[[package]]
name = "concurrent-queue"
-version = "2.1.0"
+version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c278839b831783b70278b14df4d45e1beb1aad306c07bb796637de9a0e323e8e"
+checksum = "62ec6771ecfa0762d24683ee5a32ad78487a3d3afdc0fb8cae19d2c5deb50b7c"
dependencies = [
"crossbeam-utils",
]
@@ -523,9 +524,9 @@ dependencies = [
[[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"
@@ -715,7 +716,7 @@ version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35b50dba0afdca80b187392b24f2499a88c336d5a8493e4b4ccfb608708be56a"
dependencies = [
- "bitflags 2.0.2",
+ "bitflags 2.1.0",
"proc-macro2",
"proc-macro2-diagnostics",
"quote",
@@ -839,13 +840,13 @@ dependencies = [
[[package]]
name = "errno"
-version = "0.3.0"
+version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "50d6a0976c999d473fe89ad888d5a284e55366d9dc9038b1ba2aa15128c4afa0"
+checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a"
dependencies = [
"errno-dragonfly",
"libc",
- "windows-sys 0.45.0",
+ "windows-sys 0.48.0",
]
[[package]]
@@ -996,9 +997,9 @@ checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964"
[[package]]
name = "futures-lite"
-version = "1.12.0"
+version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48"
+checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce"
dependencies = [
"fastrand",
"futures-core",
@@ -1081,9 +1082,9 @@ dependencies = [
[[package]]
name = "getrandom"
-version = "0.2.8"
+version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
+checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4"
dependencies = [
"cfg-if",
"libc",
@@ -1301,16 +1302,16 @@ dependencies = [
[[package]]
name = "iana-time-zone"
-version = "0.1.54"
+version = "0.1.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0c17cc76786e99f8d2f055c11159e7f0091c42474dcc3189fbab96072e873e6d"
+checksum = "0722cd7114b7de04316e7ea5456a0bbb20e4adb46fd27a3697adb812cff0f37c"
dependencies = [
"android_system_properties",
"core-foundation-sys",
"iana-time-zone-haiku",
"js-sys",
"wasm-bindgen",
- "windows 0.46.0",
+ "windows 0.48.0",
]
[[package]]
@@ -1378,13 +1379,13 @@ dependencies = [
[[package]]
name = "io-lifetimes"
-version = "1.0.9"
+version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09270fd4fa1111bc614ed2246c7ef56239a3063d5be0d1ec3b589c505d400aeb"
+checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220"
dependencies = [
"hermit-abi 0.3.1",
"libc",
- "windows-sys 0.45.0",
+ "windows-sys 0.48.0",
]
[[package]]
@@ -1407,14 +1408,14 @@ checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f"
[[package]]
name = "is-terminal"
-version = "0.4.6"
+version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "256017f749ab3117e93acb91063009e1f1bb56d03965b14c2c8df4eb02c524d8"
+checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f"
dependencies = [
"hermit-abi 0.3.1",
"io-lifetimes",
"rustix",
- "windows-sys 0.45.0",
+ "windows-sys 0.48.0",
]
[[package]]
@@ -1509,15 +1510,15 @@ dependencies = [
[[package]]
name = "libc"
-version = "0.2.140"
+version = "0.2.141"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c"
+checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5"
[[package]]
name = "libmimalloc-sys"
-version = "0.1.30"
+version = "0.1.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd8c7cbf8b89019683667e347572e6d55a7df7ea36b0c4ce69961b0cde67b174"
+checksum = "43a558e3d911bc3c7bfc8c78bc580b404d6e51c1cefbf656e176a94b49b0df40"
dependencies = [
"cc",
"libc",
@@ -1658,9 +1659,9 @@ dependencies = [
[[package]]
name = "mimalloc"
-version = "0.1.34"
+version = "0.1.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9dcb174b18635f7561a0c6c9fc2ce57218ac7523cf72c50af80e2d79ab8f3ba1"
+checksum = "3d88dad3f985ec267a3fcb7a1726f5cb1a7e8cad8b646e70a84f967210df23da"
dependencies = [
"libmimalloc-sys",
]
@@ -1712,7 +1713,7 @@ dependencies = [
"log",
"memchr",
"mime",
- "spin 0.9.7",
+ "spin 0.9.8",
"tokio",
"tokio-util",
"version_check",
@@ -1846,9 +1847,9 @@ checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
[[package]]
name = "openssl"
-version = "0.10.49"
+version = "0.10.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4d2f106ab837a24e03672c59b1239669a0596406ff657c3c0835b6b7f0f35a33"
+checksum = "7e30d8bc91859781f0a943411186324d580f2bbeb71b452fe91ae344806af3f1"
dependencies = [
"bitflags 1.3.2",
"cfg-if",
@@ -1887,9 +1888,9 @@ dependencies = [
[[package]]
name = "openssl-sys"
-version = "0.9.84"
+version = "0.9.85"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3a20eace9dc2d82904039cb76dcf50fb1a0bba071cfd1629720b5d6f1ddba0fa"
+checksum = "0d3d193fb1488ad46ffe3aaabc912cc931d02ee8518fe2959aea8ef52718b0c0"
dependencies = [
"cc",
"libc",
@@ -1906,9 +1907,9 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
[[package]]
name = "parking"
-version = "2.0.0"
+version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72"
+checksum = "14f2252c834a40ed9bb5422029649578e63aa341ac401f74e719dd1afda8394e"
[[package]]
name = "parking_lot"
@@ -2105,9 +2106,9 @@ checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160"
[[package]]
name = "polling"
-version = "2.6.0"
+version = "2.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7e1f879b2998099c2d69ab9605d145d5b661195627eccc680002c4918a7fb6fa"
+checksum = "4be1c66a6add46bff50935c313dae30a5030cf8385c5206e8a95e9e9def974aa"
dependencies = [
"autocfg",
"bitflags 1.3.2",
@@ -2116,7 +2117,7 @@ dependencies = [
"libc",
"log",
"pin-project-lite",
- "windows-sys 0.45.0",
+ "windows-sys 0.48.0",
]
[[package]]
@@ -2160,9 +2161,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
-version = "1.0.55"
+version = "1.0.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d0dd4be24fcdcfeaa12a432d588dc59bbad6cad3510c67e74a2b6b2fc950564"
+checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435"
dependencies = [
"unicode-ident",
]
@@ -2440,8 +2441,7 @@ dependencies = [
[[package]]
name = "rocket"
version = "0.5.0-rc.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "58734f7401ae5cfd129685b48f61182331745b357b96f2367f01aebaf1cc9cc9"
+source = "git+https://github.com/SergioBenitez/Rocket?rev=a82508b403420bd941c32ddec3ee3e4875f2b8a5#a82508b403420bd941c32ddec3ee3e4875f2b8a5"
dependencies = [
"async-stream",
"async-trait",
@@ -2479,8 +2479,7 @@ dependencies = [
[[package]]
name = "rocket_codegen"
version = "0.5.0-rc.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7093353f14228c744982e409259fb54878ba9563d08214f2d880d59ff2fc508b"
+source = "git+https://github.com/SergioBenitez/Rocket?rev=a82508b403420bd941c32ddec3ee3e4875f2b8a5#a82508b403420bd941c32ddec3ee3e4875f2b8a5"
dependencies = [
"devise",
"glob",
@@ -2495,8 +2494,7 @@ dependencies = [
[[package]]
name = "rocket_http"
version = "0.5.0-rc.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "936012c99162a03a67f37f9836d5f938f662e26f2717809761a9ac46432090f4"
+source = "git+https://github.com/SergioBenitez/Rocket?rev=a82508b403420bd941c32ddec3ee3e4875f2b8a5#a82508b403420bd941c32ddec3ee3e4875f2b8a5"
dependencies = [
"cookie 0.17.0",
"either",
@@ -2523,6 +2521,15 @@ dependencies = [
]
[[package]]
+name = "rocket_ws"
+version = "0.1.0-rc.3"
+source = "git+https://github.com/SergioBenitez/Rocket?rev=a82508b403420bd941c32ddec3ee3e4875f2b8a5#a82508b403420bd941c32ddec3ee3e4875f2b8a5"
+dependencies = [
+ "rocket",
+ "tokio-tungstenite",
+]
+
+[[package]]
name = "rpassword"
version = "7.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2545,28 +2552,28 @@ dependencies = [
[[package]]
name = "rustix"
-version = "0.37.6"
+version = "0.37.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d097081ed288dfe45699b72f5b5d648e5f15d64d900c7080273baa20c16a6849"
+checksum = "85597d61f83914ddeba6a47b3b8ffe7365107221c2e557ed94426489fefb5f77"
dependencies = [
"bitflags 1.3.2",
"errno",
"io-lifetimes",
"libc",
"linux-raw-sys",
- "windows-sys 0.45.0",
+ "windows-sys 0.48.0",
]
[[package]]
name = "rustls"
-version = "0.20.8"
+version = "0.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f"
+checksum = "07180898a28ed6a7f7ba2311594308f595e3dd2e3c3812fa0a80a47b45f17e5d"
dependencies = [
"log",
"ring",
+ "rustls-webpki",
"sct",
- "webpki",
]
[[package]]
@@ -2579,6 +2586,16 @@ dependencies = [
]
[[package]]
+name = "rustls-webpki"
+version = "0.100.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d6207cd5ed3d8dca7816f8f3725513a34609c0c765bf652b8c3cb4cfd87db46b"
+dependencies = [
+ "ring",
+ "untrusted",
+]
+
+[[package]]
name = "rustversion"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2839,9 +2856,9 @@ checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
[[package]]
name = "spin"
-version = "0.9.7"
+version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c0959fd6f767df20b231736396e4f602171e00d95205676286e79d4a4eb67bef"
+checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
[[package]]
name = "stable-pattern"
@@ -3055,13 +3072,12 @@ dependencies = [
[[package]]
name = "tokio-rustls"
-version = "0.23.4"
+version = "0.24.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59"
+checksum = "e0d409377ff5b1e3ca6437aa86c1eb7d40c134bfec254e44c830defa92669db5"
dependencies = [
"rustls",
"tokio",
- "webpki",
]
[[package]]
@@ -3363,9 +3379,9 @@ checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
[[package]]
name = "uuid"
-version = "1.3.0"
+version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1674845326ee10d37ca60470760d4288a6f80f304007d92e5c53bab78c9cfd79"
+checksum = "5b55a3fef2a1e3b3a00ce878640918820d3c51081576ac657d23af9fc7928fdb"
dependencies = [
"getrandom",
]
@@ -3413,7 +3429,6 @@ dependencies = [
"job_scheduler_ng",
"jsonwebtoken",
"lettre",
- "libmimalloc-sys",
"libsqlite3-sys",
"log",
"mimalloc",
@@ -3430,6 +3445,7 @@ dependencies = [
"ring",
"rmpv",
"rocket",
+ "rocket_ws",
"rpassword",
"semver",
"serde",
@@ -3606,16 +3622,6 @@ dependencies = [
]
[[package]]
-name = "webpki"
-version = "0.22.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd"
-dependencies = [
- "ring",
- "untrusted",
-]
-
-[[package]]
name = "which"
version = "4.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3669,16 +3675,16 @@ version = "0.44.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e745dab35a0c4c77aa3ce42d595e13d2003d6902d6b08c9ef5fc326d08da12b"
dependencies = [
- "windows-targets",
+ "windows-targets 0.42.2",
]
[[package]]
name = "windows"
-version = "0.46.0"
+version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cdacb41e6a96a052c6cb63a144f24900236121c6f63f4f8219fef5977ecb0c25"
+checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f"
dependencies = [
- "windows-targets",
+ "windows-targets 0.48.0",
]
[[package]]
@@ -3687,13 +3693,13 @@ version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
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",
+ "windows_aarch64_gnullvm 0.42.2",
+ "windows_aarch64_msvc 0.42.2",
+ "windows_i686_gnu 0.42.2",
+ "windows_i686_msvc 0.42.2",
+ "windows_x86_64_gnu 0.42.2",
+ "windows_x86_64_gnullvm 0.42.2",
+ "windows_x86_64_msvc 0.42.2",
]
[[package]]
@@ -3702,7 +3708,16 @@ version = "0.45.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
dependencies = [
- "windows-targets",
+ "windows-targets 0.42.2",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
+dependencies = [
+ "windows-targets 0.48.0",
]
[[package]]
@@ -3711,13 +3726,28 @@ version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
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",
+ "windows_aarch64_gnullvm 0.42.2",
+ "windows_aarch64_msvc 0.42.2",
+ "windows_i686_gnu 0.42.2",
+ "windows_i686_msvc 0.42.2",
+ "windows_x86_64_gnu 0.42.2",
+ "windows_x86_64_gnullvm 0.42.2",
+ "windows_x86_64_msvc 0.42.2",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5"
+dependencies = [
+ "windows_aarch64_gnullvm 0.48.0",
+ "windows_aarch64_msvc 0.48.0",
+ "windows_i686_gnu 0.48.0",
+ "windows_i686_msvc 0.48.0",
+ "windows_x86_64_gnu 0.48.0",
+ "windows_x86_64_gnullvm 0.48.0",
+ "windows_x86_64_msvc 0.48.0",
]
[[package]]
@@ -3727,42 +3757,84 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
+
+[[package]]
name = "windows_aarch64_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
[[package]]
+name = "windows_aarch64_msvc"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
+
+[[package]]
name = "windows_i686_gnu"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
[[package]]
+name = "windows_i686_gnu"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
+
+[[package]]
name = "windows_i686_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
[[package]]
+name = "windows_i686_msvc"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
+
+[[package]]
name = "windows_x86_64_gnu"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
[[package]]
+name = "windows_x86_64_gnu"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
+
+[[package]]
name = "windows_x86_64_gnullvm"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
+
+[[package]]
name = "windows_x86_64_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
[[package]]
+name = "windows_x86_64_msvc"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
+
+[[package]]
name = "winreg"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
@@ -56,6 +56,8 @@ num-derive = "0.3.3"
# Web framework
rocket = { version = "0.5.0-rc.3", features = ["tls", "json"], default-features = false }
+# rocket_ws = { version ="0.1.0-rc.3" }
+rocket_ws = { git = 'https://github.com/SergioBenitez/Rocket', rev = "a82508b403420bd941c32ddec3ee3e4875f2b8a5" }
# WebSockets libraries
tokio-tungstenite = "0.18.0"
@@ -85,11 +87,11 @@ rand = { version = "0.8.5", features = ["small_rng"] }
ring = "0.16.20"
# UUID generation
-uuid = { version = "1.3.0", features = ["v4"] }
+uuid = { version = "1.3.1", features = ["v4"] }
# Date and time libraries
chrono = { version = "0.4.24", features = ["clock", "serde"], default-features = false }
-chrono-tz = "0.8.1"
+chrono-tz = "0.8.2"
time = "0.3.20"
# Job scheduler
@@ -114,7 +116,7 @@ webauthn-rs = "0.3.2"
url = "2.3.1"
# Email libraries
-lettre = { version = "0.10.3", features = ["smtp-transport", "sendmail-transport", "builder", "serde", "tokio1-native-tls", "hostname", "tracing", "tokio1"], default-features = false }
+lettre = { version = "0.10.4", features = ["smtp-transport", "sendmail-transport", "builder", "serde", "tokio1-native-tls", "hostname", "tracing", "tokio1"], default-features = false }
percent-encoding = "2.2.0" # URL encoding library used for URL's in the emails
email_address = "0.2.4"
@@ -138,7 +140,7 @@ cookie = "0.16.2"
cookie_store = "0.19.0"
# Used by U2F, JWT and PostgreSQL
-openssl = "0.10.48"
+openssl = "0.10.50"
# CLI argument parsing
pico-args = "0.5.0"
@@ -152,8 +154,7 @@ semver = "1.0.17"
# Allow overriding the default memory allocator
# Mainly used for the musl builds, since the default musl malloc is very slow
-mimalloc = { version = "=0.1.34", features = ["secure"], default-features = false, optional = true }
-libmimalloc-sys = "=0.1.30"
+mimalloc = { version = "0.1.36", features = ["secure"], default-features = false, optional = true }
which = "4.4.0"
# Argon2 library with support for the PHC format
@@ -162,6 +163,10 @@ argon2 = "0.5.0"
# Reading a password from the cli for generating the Argon2id ADMIN_TOKEN
rpassword = "7.2.0"
+[patch.crates-io]
+rocket = { git = 'https://github.com/SergioBenitez/Rocket', rev = 'a82508b403420bd941c32ddec3ee3e4875f2b8a5' }
+# rocket_ws = { git = 'https://github.com/SergioBenitez/Rocket', rev = 'a82508b403420bd941c32ddec3ee3e4875f2b8a5' }
+
# Strip debuginfo from the release builds
# Also enable thin LTO for some optimizations
[profile.release]
diff --git a/src/api/notifications.rs b/src/api/notifications.rs
@@ -1,16 +1,15 @@
use std::{
- net::SocketAddr,
- sync::{
- atomic::{AtomicBool, Ordering},
- Arc,
- },
+ net::{IpAddr, SocketAddr},
+ sync::Arc,
time::Duration,
};
use chrono::NaiveDateTime;
-use futures::{SinkExt, StreamExt};
use rmpv::Value;
-use rocket::Route;
+use rocket::{
+ futures::{SinkExt, StreamExt},
+ Route,
+};
use tokio::{
net::{TcpListener, TcpStream},
sync::mpsc::Sender,
@@ -21,34 +20,127 @@ use tokio_tungstenite::{
};
use crate::{
- api::EmptyResult,
- db::models::{Cipher, Folder, Send, User},
+ auth::ClientIp,
+ db::models::{Cipher, Folder, Send as DbSend, User},
Error, CONFIG,
};
+use once_cell::sync::Lazy;
+
+static WS_USERS: Lazy<Arc<WebSocketUsers>> = Lazy::new(|| {
+ Arc::new(WebSocketUsers {
+ map: Arc::new(dashmap::DashMap::new()),
+ })
+});
+
pub fn routes() -> Vec<Route> {
- routes![websockets_err]
+ routes![websockets_hub]
+}
+
+#[derive(FromForm, Debug)]
+struct WsAccessToken {
+ access_token: Option<String>,
}
-#[get("/hub")]
-fn websockets_err() -> EmptyResult {
- static SHOW_WEBSOCKETS_MSG: AtomicBool = AtomicBool::new(true);
-
- if CONFIG.websocket_enabled()
- && SHOW_WEBSOCKETS_MSG.compare_exchange(true, false, Ordering::Relaxed, Ordering::Relaxed).is_ok()
- {
- err!(
- "
- ###########################################################
- '/notifications/hub' should be proxied to the websocket server or notifications won't work.
- Go to the Wiki for more info, or disable WebSockets setting WEBSOCKET_ENABLED=false.
- ###########################################################################################\n"
- )
- } else {
- Err(Error::empty())
+struct WSEntryMapGuard {
+ users: Arc<WebSocketUsers>,
+ user_uuid: String,
+ entry_uuid: uuid::Uuid,
+ addr: IpAddr,
+}
+
+impl WSEntryMapGuard {
+ fn new(users: Arc<WebSocketUsers>, user_uuid: String, entry_uuid: uuid::Uuid, addr: IpAddr) -> Self {
+ Self {
+ users,
+ user_uuid,
+ entry_uuid,
+ addr,
+ }
}
}
+impl Drop for WSEntryMapGuard {
+ fn drop(&mut self) {
+ info!("Closing WS connection from {}", self.addr);
+ if let Some(mut entry) = self.users.map.get_mut(&self.user_uuid) {
+ entry.retain(|(uuid, _)| uuid != &self.entry_uuid);
+ }
+ }
+}
+
+#[get("/hub?<data..>")]
+async fn websockets_hub<'r>(
+ ws: rocket_ws::WebSocket,
+ data: WsAccessToken,
+ ip: ClientIp,
+) -> Result<rocket_ws::Channel<'r>, Error> {
+ let addr = ip.ip;
+ info!("Accepting Rocket WS connection from {addr}");
+
+ let Some(token) = data.access_token else { err_code!("Invalid claim", 401) };
+ let Ok(claims) = crate::auth::decode_login(&token) else { err_code!("Invalid token", 401) };
+
+ let (mut rx, guard) = {
+ let users = Arc::clone(&WS_USERS);
+
+ // Add a channel to send messages to this client to the map
+ let entry_uuid = uuid::Uuid::new_v4();
+ let (tx, rx) = tokio::sync::mpsc::channel::<Message>(100);
+ users.map.entry(claims.sub.clone()).or_default().push((entry_uuid, tx));
+
+ // Once the guard goes out of scope, the connection will have been closed and the entry will be deleted from the map
+ (rx, WSEntryMapGuard::new(users, claims.sub, entry_uuid, addr))
+ };
+
+ Ok(ws.channel(move |mut stream| {
+ Box::pin(async move {
+ // Make sure the guard is moved into the channel future so it's not dropped earlier
+ let _guard = guard;
+ let mut interval = tokio::time::interval(Duration::from_secs(15));
+ loop {
+ tokio::select! {
+ res = stream.next() => {
+ match res {
+ Some(Ok(message)) => {
+ match message {
+ // Respond to any pings
+ Message::Ping(ping) => stream.send(Message::Pong(ping)).await?,
+ Message::Pong(_) => {/* Ignored */},
+
+ // We should receive an initial message with the protocol and version, and we will reply to it
+ Message::Text(ref message) => {
+ let msg = message.strip_suffix(RECORD_SEPARATOR as char).unwrap_or(message);
+
+ if serde_json::from_str(msg).ok() == Some(INITIAL_MESSAGE) {
+ stream.send(Message::binary(INITIAL_RESPONSE)).await?;
+ continue;
+ }
+ }
+ // Just echo anything else the client sends
+ _ => stream.send(message).await?,
+ }
+ }
+ _ => break,
+ }
+ }
+
+ res = rx.recv() => {
+ match res {
+ Some(res) => stream.send(res).await?,
+ None => break,
+ }
+ }
+
+ _ = interval.tick() => stream.send(Message::Ping(create_ping())).await?
+ }
+ }
+
+ Ok(())
+ })
+ }))
+}
+
//
// Websockets server
//
@@ -127,8 +219,8 @@ impl WebSocketUsers {
async fn send_update(&self, user_uuid: &str, data: &[u8]) {
if let Some(user) = self.map.get(user_uuid).map(|v| v.clone()) {
for (_, sender) in user.iter() {
- if sender.send(Message::binary(data)).await.is_err() {
- // TODO: Delete from map here too?
+ if let Err(e) = sender.send(Message::binary(data)).await {
+ error!("Error sending WS update {e}");
}
}
}
@@ -196,7 +288,7 @@ impl WebSocketUsers {
}
}
- pub async fn send_send_update(&self, ut: UpdateType, send: &Send, user_uuids: &[String]) {
+ pub async fn send_send_update(&self, ut: UpdateType, send: &DbSend, user_uuids: &[String]) {
let user_uuid = convert_option(send.user_uuid.clone());
let data = create_update(
@@ -280,15 +372,12 @@ pub enum UpdateType {
None = 100,
}
-pub type Notify<'a> = &'a rocket::State<WebSocketUsers>;
-
-pub fn start_notification_server() -> WebSocketUsers {
- let users = WebSocketUsers {
- map: Arc::new(dashmap::DashMap::new()),
- };
+pub type Notify<'a> = &'a rocket::State<Arc<WebSocketUsers>>;
+pub fn start_notification_server() -> Arc<WebSocketUsers> {
+ let users = Arc::clone(&WS_USERS);
if CONFIG.websocket_enabled() {
- let users2 = users.clone();
+ let users2 = Arc::<WebSocketUsers>::clone(&users);
tokio::spawn(async move {
let addr = (CONFIG.websocket_address(), CONFIG.websocket_port());
info!("Starting WebSockets server on {}:{}", addr.0, addr.1);
@@ -300,7 +389,7 @@ pub fn start_notification_server() -> WebSocketUsers {
loop {
tokio::select! {
Ok((stream, addr)) = listener.accept() => {
- tokio::spawn(handle_connection(stream, users2.clone(), addr));
+ tokio::spawn(handle_connection(stream, Arc::<WebSocketUsers>::clone(&users2), addr));
}
_ = &mut shutdown_rx => {
@@ -316,7 +405,7 @@ pub fn start_notification_server() -> WebSocketUsers {
users
}
-async fn handle_connection(stream: TcpStream, users: WebSocketUsers, addr: SocketAddr) -> Result<(), Error> {
+async fn handle_connection(stream: TcpStream, users: Arc<WebSocketUsers>, addr: SocketAddr) -> Result<(), Error> {
let mut user_uuid: Option<String> = None;
info!("Accepting WS connection from {addr}");
@@ -336,41 +425,39 @@ async fn handle_connection(stream: TcpStream, users: WebSocketUsers, addr: Socke
let user_uuid = user_uuid.expect("User UUID should be set after the handshake");
- // Add a channel to send messages to this client to the map
- let entry_uuid = uuid::Uuid::new_v4();
- let (tx, mut rx) = tokio::sync::mpsc::channel(100);
- users.map.entry(user_uuid.clone()).or_default().push((entry_uuid, tx));
+ let (mut rx, guard) = {
+ // Add a channel to send messages to this client to the map
+ let entry_uuid = uuid::Uuid::new_v4();
+ let (tx, rx) = tokio::sync::mpsc::channel::<Message>(100);
+ users.map.entry(user_uuid.clone()).or_default().push((entry_uuid, tx));
+ // Once the guard goes out of scope, the connection will have been closed and the entry will be deleted from the map
+ (rx, WSEntryMapGuard::new(users, user_uuid, entry_uuid, addr.ip()))
+ };
+
+ let _guard = guard;
let mut interval = tokio::time::interval(Duration::from_secs(15));
loop {
tokio::select! {
res = stream.next() => {
match res {
Some(Ok(message)) => {
- // Respond to any pings
- if let Message::Ping(ping) = message {
- if stream.send(Message::Pong(ping)).await.is_err() {
- break;
- }
- continue;
- } else if let Message::Pong(_) = message {
- /* Ignored */
- continue;
- }
-
- // We should receive an initial message with the protocol and version, and we will reply to it
- if let Message::Text(ref message) = message {
- let msg = message.strip_suffix(RECORD_SEPARATOR as char).unwrap_or(message);
-
- if serde_json::from_str(msg).ok() == Some(INITIAL_MESSAGE) {
- stream.send(Message::binary(INITIAL_RESPONSE)).await?;
- continue;
+ match message {
+ // Respond to any pings
+ Message::Ping(ping) => stream.send(Message::Pong(ping)).await?,
+ Message::Pong(_) => {/* Ignored */},
+
+ // We should receive an initial message with the protocol and version, and we will reply to it
+ Message::Text(ref message) => {
+ let msg = message.strip_suffix(RECORD_SEPARATOR as char).unwrap_or(message);
+
+ if serde_json::from_str(msg).ok() == Some(INITIAL_MESSAGE) {
+ stream.send(Message::binary(INITIAL_RESPONSE)).await?;
+ continue;
+ }
}
- }
-
- // Just echo anything else the client sends
- if stream.send(message).await.is_err() {
- break;
+ // Just echo anything else the client sends
+ _ => stream.send(message).await?,
}
}
_ => break,
@@ -379,27 +466,15 @@ async fn handle_connection(stream: TcpStream, users: WebSocketUsers, addr: Socke
res = rx.recv() => {
match res {
- Some(res) => {
- if stream.send(res).await.is_err() {
- break;
- }
- },
+ Some(res) => stream.send(res).await?,
None => break,
}
}
- _= interval.tick() => {
- if stream.send(Message::Ping(create_ping())).await.is_err() {
- break;
- }
- }
+ _ = interval.tick() => stream.send(Message::Ping(create_ping())).await?
}
}
- info!("Closing WS connection from {addr}");
-
- // Delete from map
- users.map.entry(user_uuid).or_default().retain(|(uuid, _)| uuid != &entry_uuid);
Ok(())
}