Add barebones nRPC over websocket adapters and functionality
This commit is contained in:
parent
570c194e82
commit
6a525fa384
11 changed files with 417 additions and 652 deletions
537
Cargo.lock
generated
537
Cargo.lock
generated
|
@ -2,6 +2,12 @@
|
|||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "adler"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "aead"
|
||||
version = "0.4.3"
|
||||
|
@ -55,6 +61,15 @@ dependencies = [
|
|||
"futures-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-lock"
|
||||
version = "2.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa24f727524730b077666307f2734b4a1a1c57acb79193127dcc8914d5242dd7"
|
||||
dependencies = [
|
||||
"event-listener",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-recursion"
|
||||
version = "1.0.4"
|
||||
|
@ -89,12 +104,6 @@ version = "0.13.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a"
|
||||
|
||||
[[package]]
|
||||
name = "beef"
|
||||
version = "0.5.2"
|
||||
|
@ -109,9 +118,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
|||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.10.4"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
|
||||
checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
@ -174,6 +183,12 @@ dependencies = [
|
|||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "convert_case"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.2.6"
|
||||
|
@ -183,6 +198,15 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.15"
|
||||
|
@ -192,16 +216,6 @@ dependencies = [
|
|||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ctr"
|
||||
version = "0.8.0"
|
||||
|
@ -212,13 +226,25 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.6"
|
||||
name = "derive_more"
|
||||
version = "0.99.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f"
|
||||
checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"crypto-common",
|
||||
"convert_case",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustc_version",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -333,6 +359,17 @@ version = "0.4.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.0.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"libz-sys",
|
||||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
|
@ -501,56 +538,12 @@ dependencies = [
|
|||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "h2"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "66b91535aa35fea1523ad1b86cb6b53c28e0ae566ba4a460f4457e936cad7c6f"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"fnv",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"futures-util",
|
||||
"http",
|
||||
"indexmap",
|
||||
"slab",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||
|
||||
[[package]]
|
||||
name = "headers"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3e372db8e5c0d213e0cd0b9be18be2aca3d44cf2fe30a9d46a65581cd454584"
|
||||
dependencies = [
|
||||
"base64 0.13.1",
|
||||
"bitflags",
|
||||
"bytes",
|
||||
"headers-core",
|
||||
"http",
|
||||
"httpdate",
|
||||
"mime",
|
||||
"sha1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "headers-core"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429"
|
||||
dependencies = [
|
||||
"http",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.1"
|
||||
|
@ -595,53 +588,12 @@ dependencies = [
|
|||
"itoa",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http-body"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"http",
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "httparse"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
|
||||
|
||||
[[package]]
|
||||
name = "httpdate"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
|
||||
|
||||
[[package]]
|
||||
name = "hyper"
|
||||
version = "0.14.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2",
|
||||
"http",
|
||||
"http-body",
|
||||
"httparse",
|
||||
"httpdate",
|
||||
"itoa",
|
||||
"pin-project-lite",
|
||||
"socket2",
|
||||
"tokio",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
"want",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.3.0"
|
||||
|
@ -718,12 +670,33 @@ version = "0.2.141"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5"
|
||||
|
||||
[[package]]
|
||||
name = "libz-sys"
|
||||
version = "1.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9702761c3935f8cc2f101793272e202c72b99da8f4224a19ddcf1279a6450bbf"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.17"
|
||||
|
@ -795,19 +768,12 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "mime"
|
||||
version = "0.3.17"
|
||||
name = "miniz_oxide"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
||||
|
||||
[[package]]
|
||||
name = "mime_guess"
|
||||
version = "2.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef"
|
||||
checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa"
|
||||
dependencies = [
|
||||
"mime",
|
||||
"unicase",
|
||||
"adler",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -828,25 +794,11 @@ version = "0.8.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a"
|
||||
|
||||
[[package]]
|
||||
name = "multiparty"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed1ec6589a6d4a1e0b33b4c0a3f6ee96dfba88ebdb3da51403fd7cf0a24a4b04"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"httparse",
|
||||
"memchr",
|
||||
"pin-project-lite",
|
||||
"try-lock",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nrpc"
|
||||
version = "0.2.0"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8770a9a12e53035a536e41b7899d72bc423b2b8c17402c8f0dbe44d6bb255ac6"
|
||||
checksum = "6f41caeb65399490c6f68ab2527a833d6f2e9b0d7d5ffc4b062f1484b3fa61cd"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bytes",
|
||||
|
@ -855,9 +807,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "nrpc-build"
|
||||
version = "0.5.0"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f5914c2bfd187a4bdfa7a69330e1ef4d8dea4060d8a08bf146f622aa7f176680"
|
||||
checksum = "5b598ecce0e6d4b2cb367143696174ae24bff5eb4aeb1d8eccffbfeef75fc68e"
|
||||
dependencies = [
|
||||
"nrpc",
|
||||
"prettyplease 0.2.4",
|
||||
|
@ -897,6 +849,29 @@ version = "0.3.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.9.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall 0.2.16",
|
||||
"smallvec",
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.2.0"
|
||||
|
@ -945,6 +920,12 @@ version = "0.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160"
|
||||
|
||||
[[package]]
|
||||
name = "polyval"
|
||||
version = "0.5.3"
|
||||
|
@ -1125,6 +1106,75 @@ dependencies = [
|
|||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ratchet_core"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "854bf6632d9f5c7fa7f77cbc332f2b0a8dfb2acc36c3f351fc36bf40f2759728"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"bitflags",
|
||||
"bytes",
|
||||
"derive_more",
|
||||
"either",
|
||||
"fnv",
|
||||
"http",
|
||||
"httparse",
|
||||
"log",
|
||||
"rand",
|
||||
"ratchet_ext",
|
||||
"sha-1",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ratchet_deflate"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0b144cb23a76d810b25737f4b87943fdfd7772b423bdc15c2b3820849207adc"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"flate2",
|
||||
"http",
|
||||
"log",
|
||||
"ratchet_ext",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ratchet_ext"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67f97bb0776d195720319a1e9f08fa343fe3f9f0b7ebf9d97d5926ce50b8e1ad"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"http",
|
||||
"httparse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ratchet_rs"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7dba456fc23026b46ce0936d109ce3e73b4a592baf0dda0f83d49886c5e5f83"
|
||||
dependencies = [
|
||||
"ratchet_core",
|
||||
"ratchet_deflate",
|
||||
"ratchet_ext",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.3.5"
|
||||
|
@ -1149,6 +1199,15 @@ version = "0.6.29"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
|
||||
dependencies = [
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.37.11"
|
||||
|
@ -1163,15 +1222,6 @@ dependencies = [
|
|||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-pemfile"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b"
|
||||
dependencies = [
|
||||
"base64 0.21.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.13"
|
||||
|
@ -1184,6 +1234,18 @@ version = "1.0.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.160"
|
||||
|
@ -1202,26 +1264,25 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_urlencoded"
|
||||
version = "0.7.1"
|
||||
name = "sha-1"
|
||||
version = "0.9.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
|
||||
dependencies = [
|
||||
"form_urlencoded",
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha1"
|
||||
version = "0.10.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3"
|
||||
checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
"opaque-debug",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1233,6 +1294,12 @@ dependencies = [
|
|||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.4.9"
|
||||
|
@ -1279,7 +1346,7 @@ checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998"
|
|||
dependencies = [
|
||||
"cfg-if",
|
||||
"fastrand",
|
||||
"redox_syscall",
|
||||
"redox_syscall 0.3.5",
|
||||
"rustix",
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
@ -1330,98 +1397,37 @@ dependencies = [
|
|||
"libc",
|
||||
"mio",
|
||||
"num_cpus",
|
||||
"parking_lot",
|
||||
"pin-project-lite",
|
||||
"signal-hook-registry",
|
||||
"socket2",
|
||||
"tokio-macros",
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-stream"
|
||||
version = "0.1.12"
|
||||
name = "tokio-macros"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fb52b74f05dbf495a8fba459fdc331812b96aa086d9eb78101fa0d4569c3313"
|
||||
checksum = "61a573bdc87985e9d6ddeed1b3d864e8a302c847e40d647746df2f1de209d1ce"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-tungstenite"
|
||||
version = "0.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "54319c93411147bced34cb5609a80e0a8e44c5999c93903a81cd866630ec0bfd"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"log",
|
||||
"tokio",
|
||||
"tungstenite",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.15",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-util"
|
||||
version = "0.7.7"
|
||||
version = "0.6.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5427d89453009325de0d8f342c9490009f76e999cb7672d77e46267448f7e6b2"
|
||||
checksum = "36943ee01a6d67977dd3f84a5a1d2efeb4ada3a1ae771cadfaa535d9d9fc6507"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"log",
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tower-service"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
|
||||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
version = "0.1.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"log",
|
||||
"pin-project-lite",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-core"
|
||||
version = "0.1.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "try-lock"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed"
|
||||
|
||||
[[package]]
|
||||
name = "tungstenite"
|
||||
version = "0.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "30ee6ab729cd4cf0fd55218530c4522ed30b7b6081752839b68fcec8d0960788"
|
||||
dependencies = [
|
||||
"base64 0.13.1",
|
||||
"byteorder",
|
||||
"bytes",
|
||||
"http",
|
||||
"httparse",
|
||||
"log",
|
||||
"rand",
|
||||
"sha1",
|
||||
"thiserror",
|
||||
"url",
|
||||
"utf-8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1430,15 +1436,6 @@ version = "1.16.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
|
||||
|
||||
[[package]]
|
||||
name = "unicase"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
|
||||
dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.13"
|
||||
|
@ -1491,6 +1488,7 @@ dependencies = [
|
|||
name = "usdpl-back"
|
||||
version = "0.11.0"
|
||||
dependencies = [
|
||||
"async-lock",
|
||||
"async-recursion",
|
||||
"async-trait",
|
||||
"bytes",
|
||||
|
@ -1499,10 +1497,10 @@ dependencies = [
|
|||
"log",
|
||||
"nrpc",
|
||||
"obfstr",
|
||||
"ratchet_rs",
|
||||
"tokio",
|
||||
"usdpl-build",
|
||||
"usdpl-core",
|
||||
"warp",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1523,7 +1521,7 @@ name = "usdpl-core"
|
|||
version = "0.11.0"
|
||||
dependencies = [
|
||||
"aes-gcm-siv",
|
||||
"base64 0.13.1",
|
||||
"base64",
|
||||
"hex-literal",
|
||||
]
|
||||
|
||||
|
@ -1549,10 +1547,10 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "utf-8"
|
||||
version = "0.7.6"
|
||||
name = "vcpkg"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
|
||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
|
@ -1560,47 +1558,6 @@ version = "0.9.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "want"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0"
|
||||
dependencies = [
|
||||
"log",
|
||||
"try-lock",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "warp"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "27e1a710288f0f91a98dd8a74f05b76a10768db245ce183edf64dc1afdc3016c"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
"futures-util",
|
||||
"headers",
|
||||
"http",
|
||||
"hyper",
|
||||
"log",
|
||||
"mime",
|
||||
"mime_guess",
|
||||
"multiparty",
|
||||
"percent-encoding",
|
||||
"pin-project",
|
||||
"rustls-pemfile",
|
||||
"scoped-tls",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_urlencoded",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
"tokio-tungstenite",
|
||||
"tokio-util",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
|
|
|
@ -10,7 +10,7 @@ description = "Universal Steam Deck Plugin Library back-end"
|
|||
[features]
|
||||
default = ["blocking"]
|
||||
decky = ["usdpl-core/decky"]
|
||||
blocking = ["tokio", "tokio/rt", "tokio/rt-multi-thread"] # synchronous API for async functionality, using tokio
|
||||
blocking = [] # synchronous API for async functionality, using tokio
|
||||
encrypt = ["usdpl-core/encrypt", "obfstr", "hex"]
|
||||
|
||||
[dependencies]
|
||||
|
@ -19,12 +19,16 @@ usdpl-core = { version = "0.11", path = "../usdpl-core"}
|
|||
log = "0.4"
|
||||
|
||||
# gRPC/protobuf
|
||||
nrpc = "0.2"
|
||||
nrpc = "0.6"
|
||||
async-lock = "2.7"
|
||||
|
||||
# websocket framework
|
||||
ratchet_rs = { version = "0.3", features = [ "deflate" ] }
|
||||
|
||||
# HTTP web framework
|
||||
warp = { version = "0.3" }
|
||||
#warp = { version = "0.3" }
|
||||
bytes = { version = "1.1" }
|
||||
tokio = { version = "1", optional = true }
|
||||
tokio = { version = "1", features = [ "full" ]}
|
||||
|
||||
# this is why people don't like async
|
||||
async-trait = "0.1.57"
|
||||
|
|
|
@ -1,87 +0,0 @@
|
|||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use usdpl_core::serdes::Primitive;
|
||||
|
||||
/// A mutable function which can be called from the front-end (remotely)
|
||||
pub trait MutCallable: Send + Sync {
|
||||
/// Invoke the function
|
||||
fn call(&mut self, params: Vec<Primitive>) -> Vec<Primitive>;
|
||||
}
|
||||
|
||||
impl<F: (FnMut(Vec<Primitive>) -> Vec<Primitive>) + Send + Sync> MutCallable for F {
|
||||
fn call(&mut self, params: Vec<Primitive>) -> Vec<Primitive> {
|
||||
(self)(params)
|
||||
}
|
||||
}
|
||||
|
||||
/// A function which can be called from the front-end (remotely)
|
||||
pub trait Callable: Send + Sync {
|
||||
/// Invoke the function
|
||||
fn call(&self, params: Vec<Primitive>) -> Vec<Primitive>;
|
||||
}
|
||||
|
||||
impl<F: (Fn(Vec<Primitive>) -> Vec<Primitive>) + Send + Sync> Callable for F {
|
||||
fn call(&self, params: Vec<Primitive>) -> Vec<Primitive> {
|
||||
(self)(params)
|
||||
}
|
||||
}
|
||||
|
||||
/// An async function which can be called from the front-end (remotely)
|
||||
#[async_trait::async_trait]
|
||||
pub trait AsyncCallable: Send + Sync {
|
||||
/// Invoke the function
|
||||
async fn call(&self, params: Vec<Primitive>) -> Vec<Primitive>;
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl<F: (Fn(Vec<Primitive>) -> A) + Send + Sync, A: core::future::Future<Output=Vec<Primitive>> + Send> AsyncCallable for F {
|
||||
async fn call(&self, params: Vec<Primitive>) -> Vec<Primitive> {
|
||||
(self)(params).await
|
||||
}
|
||||
}
|
||||
|
||||
pub enum WrappedCallable {
|
||||
Blocking(Arc<Mutex<Box<dyn MutCallable>>>),
|
||||
Ref(Arc<Box<dyn Callable>>),
|
||||
Async(Arc<Box<dyn AsyncCallable>>),
|
||||
}
|
||||
|
||||
impl WrappedCallable {
|
||||
pub fn new_ref<T: Callable + 'static>(callable: T) -> Self {
|
||||
Self::Ref(Arc::new(Box::new(callable)))
|
||||
}
|
||||
|
||||
pub fn new_locking<T: MutCallable + 'static>(callable: T) -> Self {
|
||||
Self::Blocking(Arc::new(Mutex::new(Box::new(callable))))
|
||||
}
|
||||
|
||||
pub fn new_async<T: AsyncCallable + 'static>(callable: T) -> Self {
|
||||
Self::Async(Arc::new(Box::new(callable)))
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for WrappedCallable {
|
||||
fn clone(&self) -> Self {
|
||||
match self {
|
||||
Self::Blocking(x) => Self::Blocking(x.clone()),
|
||||
Self::Ref(x) => Self::Ref(x.clone()),
|
||||
Self::Async(x) => Self::Async(x.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl AsyncCallable for WrappedCallable {
|
||||
async fn call(&self, params: Vec<Primitive>) -> Vec<Primitive> {
|
||||
match self {
|
||||
Self::Blocking(mut_callable) => {
|
||||
mut_callable
|
||||
.lock()
|
||||
.expect("Failed to acquire mut_callable lock")
|
||||
.call(params)
|
||||
},
|
||||
Self::Ref(callable) => callable.call(params),
|
||||
Self::Async(async_callable) => async_callable.call(params).await,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,262 +0,0 @@
|
|||
use std::collections::HashMap;
|
||||
use std::sync::atomic::{AtomicU64, Ordering};
|
||||
|
||||
use warp::Filter;
|
||||
|
||||
use usdpl_core::serdes::{Dumpable, Loadable};
|
||||
use usdpl_core::{socket, RemoteCallResponse};
|
||||
|
||||
use super::{Callable, MutCallable, AsyncCallable, WrappedCallable};
|
||||
|
||||
static LAST_ID: AtomicU64 = AtomicU64::new(0);
|
||||
const MAX_ID_DIFFERENCE: u64 = 32;
|
||||
|
||||
//type WrappedCallable = Arc<Mutex<Box<dyn Callable>>>; // thread-safe, cloneable Callable
|
||||
|
||||
#[cfg(feature = "encrypt")]
|
||||
const NONCE: [u8; socket::NONCE_SIZE] = [0u8; socket::NONCE_SIZE];
|
||||
|
||||
/// Back-end instance for interacting with the front-end
|
||||
pub struct Instance {
|
||||
calls: HashMap<String, WrappedCallable>,
|
||||
port: u16,
|
||||
#[cfg(feature = "encrypt")]
|
||||
encryption_key: Vec<u8>,
|
||||
}
|
||||
|
||||
impl Instance {
|
||||
/// Initialise an instance of the back-end
|
||||
#[inline]
|
||||
pub fn new(port_usdpl: u16) -> Self {
|
||||
Instance {
|
||||
calls: HashMap::new(),
|
||||
port: port_usdpl,
|
||||
#[cfg(feature = "encrypt")]
|
||||
encryption_key: hex::decode(obfstr::obfstr!(env!("USDPL_ENCRYPTION_KEY"))).unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Register a thread-safe function which can be invoked by the front-end
|
||||
pub fn register<S: std::convert::Into<String>, F: Callable + 'static>(
|
||||
mut self,
|
||||
name: S,
|
||||
f: F,
|
||||
) -> Self {
|
||||
self.calls
|
||||
.insert(name.into(), WrappedCallable::new_ref(f));
|
||||
self
|
||||
}
|
||||
|
||||
/// Register a thread-unsafe function which can be invoked by the front-end
|
||||
pub fn register_blocking<S: std::convert::Into<String>, F: MutCallable + 'static>(
|
||||
mut self,
|
||||
name: S,
|
||||
f: F,
|
||||
) -> Self {
|
||||
self.calls
|
||||
.insert(name.into(), WrappedCallable::new_locking(f));
|
||||
self
|
||||
}
|
||||
|
||||
/// Register a thread-unsafe function which can be invoked by the front-end
|
||||
pub fn register_async<S: std::convert::Into<String>, F: AsyncCallable + 'static>(
|
||||
mut self,
|
||||
name: S,
|
||||
f: F,
|
||||
) -> Self {
|
||||
self.calls
|
||||
.insert(name.into(), WrappedCallable::new_async(f));
|
||||
self
|
||||
}
|
||||
|
||||
/// Run the web server instance forever, blocking this thread
|
||||
#[cfg(feature = "blocking")]
|
||||
pub fn run_blocking(&self) -> Result<(), ()> {
|
||||
let result = self.serve_internal();
|
||||
tokio::runtime::Builder::new_multi_thread()
|
||||
.enable_all()
|
||||
.build()
|
||||
.unwrap()
|
||||
.block_on(result)
|
||||
}
|
||||
|
||||
/// Run the web server forever, asynchronously
|
||||
pub async fn run(&self) -> Result<(), ()> {
|
||||
self.serve_internal().await
|
||||
}
|
||||
|
||||
#[async_recursion::async_recursion]
|
||||
async fn handle_call(
|
||||
packet: socket::Packet,
|
||||
handlers: &HashMap<String, WrappedCallable>,
|
||||
) -> socket::Packet {
|
||||
match packet {
|
||||
socket::Packet::Call(call) => {
|
||||
log::debug!("Got USDPL call {} (`{}`, params: {})", call.id, call.function, call.parameters.len());
|
||||
let last_id = LAST_ID.load(Ordering::SeqCst);
|
||||
if last_id == 0 {
|
||||
log::info!("Last id is 0, assuming resumed connection (overriding last id)");
|
||||
LAST_ID.store(call.id, Ordering::SeqCst);
|
||||
} else if call.id < MAX_ID_DIFFERENCE {
|
||||
log::info!("Call ID is low, assuming new connection (resetting last id)");
|
||||
LAST_ID.store(call.id, Ordering::SeqCst);
|
||||
} else if call.id > last_id && call.id - last_id < MAX_ID_DIFFERENCE {
|
||||
LAST_ID.store(call.id, Ordering::SeqCst);
|
||||
} else if call.id < last_id && last_id - call.id < MAX_ID_DIFFERENCE {
|
||||
// Allowed, but don't store new (lower) LAST_ID
|
||||
} else {
|
||||
#[cfg(not(debug_assertions))]
|
||||
{
|
||||
log::error!("Got USDPL call with strange ID! got:{} last id:{} (rejecting packet)", call.id, last_id);
|
||||
return socket::Packet::Invalid
|
||||
}
|
||||
#[cfg(debug_assertions)]
|
||||
log::warn!("Got USDPL call with strange ID! got:{} last id:{} (in release mode this packet will be rejected)", call.id, last_id);
|
||||
}
|
||||
//let handlers = CALLS.lock().expect("Failed to acquire CALLS lock");
|
||||
if let Some(target) = handlers.get(&call.function) {
|
||||
let result = target.call(call.parameters).await;
|
||||
socket::Packet::CallResponse(RemoteCallResponse {
|
||||
id: call.id,
|
||||
response: result,
|
||||
})
|
||||
} else {
|
||||
socket::Packet::Invalid
|
||||
}
|
||||
},
|
||||
socket::Packet::Many(packets) => {
|
||||
let mut result = Vec::with_capacity(packets.len());
|
||||
for packet in packets {
|
||||
result.push(Self::handle_call(packet, handlers).await);
|
||||
}
|
||||
socket::Packet::Many(result)
|
||||
},
|
||||
#[cfg(feature = "translate")]
|
||||
socket::Packet::Language(lang) => socket::Packet::Translations(get_all_translations(lang)),
|
||||
_ => socket::Packet::Invalid,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "encrypt"))]
|
||||
async fn process_body((data, handlers): (bytes::Bytes, HashMap<String, WrappedCallable>)) -> impl warp::Reply {
|
||||
let (packet, _) = match socket::Packet::load_base64(&data) {
|
||||
Ok(x) => x,
|
||||
Err(e) => {
|
||||
return warp::reply::with_status(
|
||||
warp::http::Response::builder()
|
||||
.body(format!("Failed to load packet: {}", e)),
|
||||
warp::http::StatusCode::from_u16(400).unwrap(),
|
||||
)
|
||||
}
|
||||
};
|
||||
//let mut buffer = [0u8; socket::PACKET_BUFFER_SIZE];
|
||||
let mut buffer = String::with_capacity(socket::PACKET_BUFFER_SIZE);
|
||||
let response = Self::handle_call(packet, &handlers).await;
|
||||
let _len = match response.dump_base64(&mut buffer) {
|
||||
Ok(x) => x,
|
||||
Err(e) => {
|
||||
return warp::reply::with_status(
|
||||
warp::http::Response::builder()
|
||||
.body(format!("Failed to dump response packet: {}", e)),
|
||||
warp::http::StatusCode::from_u16(500).unwrap(),
|
||||
)
|
||||
}
|
||||
};
|
||||
warp::reply::with_status(
|
||||
warp::http::Response::builder().body(buffer),
|
||||
warp::http::StatusCode::from_u16(200).unwrap(),
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(feature = "encrypt")]
|
||||
async fn process_body((data, handlers, key): (bytes::Bytes, HashMap<String, WrappedCallable>, Vec<u8>)) -> impl warp::Reply {
|
||||
let (packet, _) = match socket::Packet::load_encrypted(&data, &key, &NONCE) {
|
||||
Ok(x) => x,
|
||||
Err(_) => {
|
||||
return warp::reply::with_status(
|
||||
warp::http::Response::builder()
|
||||
.body("Failed to load packet".to_string()),
|
||||
warp::http::StatusCode::from_u16(400).unwrap(),
|
||||
)
|
||||
}
|
||||
};
|
||||
let mut buffer = Vec::with_capacity(socket::PACKET_BUFFER_SIZE);
|
||||
//buffer.extend(&[0u8; socket::PACKET_BUFFER_SIZE]);
|
||||
let response = Self::handle_call(packet, &handlers).await;
|
||||
let len = match response.dump_encrypted(&mut buffer, &key, &NONCE) {
|
||||
Ok(x) => x,
|
||||
Err(_) => {
|
||||
return warp::reply::with_status(
|
||||
warp::http::Response::builder()
|
||||
.body("Failed to dump response packet".to_string()),
|
||||
warp::http::StatusCode::from_u16(500).unwrap(),
|
||||
)
|
||||
}
|
||||
};
|
||||
buffer.truncate(len);
|
||||
let string: String = String::from_utf8(buffer).unwrap().into();
|
||||
warp::reply::with_status(
|
||||
warp::http::Response::builder().body(string),
|
||||
warp::http::StatusCode::from_u16(200).unwrap(),
|
||||
)
|
||||
}
|
||||
|
||||
/// Receive and execute callbacks forever
|
||||
async fn serve_internal(&self) -> Result<(), ()> {
|
||||
let handlers = self.calls.clone();
|
||||
#[cfg(not(feature = "encrypt"))]
|
||||
let input_mapper = move |data: bytes::Bytes| { (data, handlers.clone()) };
|
||||
#[cfg(feature = "encrypt")]
|
||||
let key = self.encryption_key.clone();
|
||||
#[cfg(feature = "encrypt")]
|
||||
let input_mapper = move |data: bytes::Bytes| { (data, handlers.clone(), key.clone()) };
|
||||
//self.calls = HashMap::new();
|
||||
let calls = warp::post()
|
||||
.and(warp::path!("usdpl" / "call"))
|
||||
.and(warp::body::content_length_limit(
|
||||
(socket::PACKET_BUFFER_SIZE * 2) as _,
|
||||
))
|
||||
.and(warp::body::bytes())
|
||||
.map(input_mapper)
|
||||
.then(Self::process_body)
|
||||
.map(|reply| warp::reply::with_header(reply, "Access-Control-Allow-Origin", "*"));
|
||||
#[cfg(debug_assertions)]
|
||||
warp::serve(calls).run(([0, 0, 0, 0], self.port)).await;
|
||||
#[cfg(not(debug_assertions))]
|
||||
warp::serve(calls).run(([127, 0, 0, 1], self.port)).await;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "translate")]
|
||||
fn get_all_translations(language: String) -> Vec<(String, Vec<String>)> {
|
||||
log::debug!("Loading translations for language `{}`...", language);
|
||||
let result = load_locale(&language);
|
||||
match result {
|
||||
Ok(catalog) => {
|
||||
let map = catalog.nalltext();
|
||||
let mut result = Vec::with_capacity(map.len());
|
||||
for (key, val) in map.iter() {
|
||||
result.push((key.to_owned().into(), val.iter().map(|x| x.into()).collect()));
|
||||
}
|
||||
result
|
||||
},
|
||||
Err(e) => {
|
||||
log::error!("Failed to load translations for language `{}`: {}", language, e);
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "translate")]
|
||||
fn load_locale(lang: &str) -> Result<gettext_ng::Catalog, gettext_ng::Error> {
|
||||
let path = crate::api::dirs::plugin().unwrap_or_else(|| "".into()).join("translations").join(format!("{}.mo", lang));
|
||||
let file = std::fs::File::open(path).map_err(|e| gettext_ng::Error::Io(e))?;
|
||||
gettext_ng::Catalog::parse(file)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[allow(unused_imports)]
|
||||
use super::*;
|
||||
}
|
|
@ -13,13 +13,12 @@ mod api_crankshaft;
|
|||
#[cfg(all(feature = "decky", not(any(feature = "crankshaft"))))]
|
||||
mod api_decky;
|
||||
|
||||
mod callable;
|
||||
//mod errors;
|
||||
mod instance;
|
||||
mod rpc;
|
||||
|
||||
pub use callable::{Callable, MutCallable, AsyncCallable};
|
||||
pub(crate) use callable::WrappedCallable;
|
||||
pub use instance::Instance;
|
||||
//mod errors;
|
||||
mod websockets;
|
||||
|
||||
pub use websockets::WebsocketServer as Server;
|
||||
//pub use errors::{ServerError, ServerResult};
|
||||
|
||||
/// USDPL backend API.
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
mod registry;
|
||||
pub use registry::ServiceRegistry;
|
42
usdpl-back/src/rpc/registry.rs
Normal file
42
usdpl-back/src/rpc/registry.rs
Normal file
|
@ -0,0 +1,42 @@
|
|||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use async_lock::Mutex;
|
||||
|
||||
use nrpc::{ServerService, ServiceError};
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
pub struct ServiceRegistry<'a> {
|
||||
entries: HashMap<String, Arc<Mutex<Box<dyn ServerService + Send + 'a>>>>,
|
||||
}
|
||||
|
||||
impl<'a> ServiceRegistry<'a> {
|
||||
/*pub async fn call(&self, package: &str, service: &str, method: &str, data: bytes::Bytes) -> Result<bytes::Bytes, ServiceError> {
|
||||
let key = Self::descriptor(package, service);
|
||||
self.call_descriptor(&key, method, data).await
|
||||
}
|
||||
|
||||
fn descriptor(package: &str, service: &str) -> String {
|
||||
format!("{}.{}", package, service)
|
||||
}*/
|
||||
|
||||
pub async fn call_descriptor(&self, descriptor: &str, method: &str, data: bytes::Bytes) -> Result<bytes::Bytes, ServiceError> {
|
||||
if let Some(service) = self.entries.get(descriptor) {
|
||||
let mut output = bytes::BytesMut::new();
|
||||
let mut service_lock = service.lock_arc().await;
|
||||
service_lock.call(method, data, &mut output).await?;
|
||||
Ok(output.into())
|
||||
} else {
|
||||
Err(ServiceError::ServiceNotFound)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn register<S: ServerService + Send + 'a>(&mut self, service: S) -> &mut Self {
|
||||
let key = service.descriptor().to_owned();
|
||||
self.entries.insert(key, Arc::new(Mutex::new(Box::new(service))));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
}
|
108
usdpl-back/src/websockets.rs
Normal file
108
usdpl-back/src/websockets.rs
Normal file
|
@ -0,0 +1,108 @@
|
|||
use bytes::BytesMut;
|
||||
use ratchet_rs::deflate::DeflateExtProvider;
|
||||
use ratchet_rs::{Error as RatchetError, Message, ProtocolRegistry, WebSocketConfig};
|
||||
use tokio::net::{TcpListener, TcpStream};
|
||||
|
||||
use crate::rpc::ServiceRegistry;
|
||||
|
||||
struct MethodDescriptor<'a> {
|
||||
service: &'a str,
|
||||
method: &'a str,
|
||||
}
|
||||
|
||||
/// Handler for communication to and from the front-end
|
||||
pub struct WebsocketServer {
|
||||
services: ServiceRegistry<'static>,
|
||||
port: u16,
|
||||
}
|
||||
|
||||
impl WebsocketServer {
|
||||
/// Initialise an instance of the back-end websocket server
|
||||
pub fn new(port_usdpl: u16) -> Self {
|
||||
Self {
|
||||
services: ServiceRegistry::new(),
|
||||
port: port_usdpl,
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the service registry that the server handles
|
||||
pub fn registry(&mut self) -> &'_ mut ServiceRegistry<'static> {
|
||||
&mut self.services
|
||||
}
|
||||
|
||||
/// Run the web server forever, asynchronously
|
||||
pub async fn run(&self) -> std::io::Result<()> {
|
||||
#[cfg(debug_assertions)]
|
||||
let addr = (std::net::Ipv4Addr::UNSPECIFIED, self.port);
|
||||
#[cfg(not(debug_assertions))]
|
||||
let addr = (std::net::Ipv4Addr::LOCALHOST, self.port);
|
||||
|
||||
let tcp = TcpListener::bind(addr).await?;
|
||||
|
||||
while let Ok((stream, _addr_do_not_use)) = tcp.accept().await {
|
||||
tokio::spawn(Self::connection_handler(self.services.clone(), stream));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn connection_handler(services: ServiceRegistry<'static>, stream: TcpStream) -> Result<(), RatchetError> {
|
||||
let upgraded = ratchet_rs::accept_with(
|
||||
stream,
|
||||
WebSocketConfig::default(),
|
||||
DeflateExtProvider::default(),
|
||||
ProtocolRegistry::new(["usdpl-nrpc"])?,
|
||||
)
|
||||
.await?
|
||||
.upgrade()
|
||||
.await?;
|
||||
|
||||
let request_path = upgraded.request.uri().path();
|
||||
|
||||
let mut websocket = upgraded.websocket;
|
||||
|
||||
let descriptor = Self::parse_uri_path(request_path)
|
||||
.map_err(|e| RatchetError::with_cause(ratchet_rs::ErrorKind::Protocol, e))?;
|
||||
|
||||
let mut buf = BytesMut::new();
|
||||
loop {
|
||||
match websocket.read(&mut buf).await? {
|
||||
Message::Text => return Err(RatchetError::with_cause(ratchet_rs::ErrorKind::Protocol, "Websocket text messages are not accepted")),
|
||||
Message::Binary => {
|
||||
let response = services.call_descriptor(
|
||||
descriptor.service,
|
||||
descriptor.method,
|
||||
buf.clone().freeze()
|
||||
)
|
||||
.await
|
||||
.map_err(|e| RatchetError::with_cause(ratchet_rs::ErrorKind::Protocol, e.to_string()))?;
|
||||
websocket.write_binary(response).await?;
|
||||
},
|
||||
Message::Ping(x) => websocket.write_pong(x).await?,
|
||||
Message::Pong(_) => {},
|
||||
Message::Close(_) => break,
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn parse_uri_path<'a>(path: &'a str) -> Result<MethodDescriptor<'a>, &'static str> {
|
||||
let mut iter = path.split('/');
|
||||
if let Some(service) = iter.next() {
|
||||
if let Some(method) = iter.next() {
|
||||
if iter.next().is_none() {
|
||||
return Ok(MethodDescriptor {
|
||||
service,
|
||||
method
|
||||
});
|
||||
} else {
|
||||
Err("URL path has too many separators")
|
||||
}
|
||||
} else {
|
||||
Err("URL path has no method")
|
||||
}
|
||||
} else {
|
||||
Err("URL path has no service")
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,7 +6,7 @@ edition = "2021"
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
nrpc-build = "0.5"
|
||||
nrpc-build = "0.6"
|
||||
prost-build = "0.11"
|
||||
prost-types = "0.11"
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ async-channel = "1.8"
|
|||
obfstr = { version = "0.3", optional = true }
|
||||
hex = { version = "0.4", optional = true }
|
||||
|
||||
nrpc = "0.2"
|
||||
nrpc = "0.6"
|
||||
usdpl-core = { version = "0.11", path = "../usdpl-core" }
|
||||
prost = "0.11"
|
||||
|
||||
|
|
|
@ -51,15 +51,17 @@ impl WebSocketHandler {
|
|||
#[async_trait::async_trait]
|
||||
impl ClientHandler for WebSocketHandler {
|
||||
async fn call(&mut self,
|
||||
package: &str,
|
||||
service: &str,
|
||||
method: &str,
|
||||
input: bytes::Bytes,
|
||||
output: &mut bytes::BytesMut) -> Result<(), ServiceError> {
|
||||
let id = LAST_ID.fetch_add(1, Ordering::SeqCst);
|
||||
let url = format!(
|
||||
"ws://usdpl-ws-{}.localhost:{}/{}/{}",
|
||||
"ws://usdpl-ws-{}.localhost:{}/{}.{}/{}",
|
||||
id,
|
||||
self.port,
|
||||
package,
|
||||
service,
|
||||
method,
|
||||
);
|
||||
|
|
Loading…
Reference in a new issue