From 89c69eae8e75d2b00794087d9ef74fd4856d0f88 Mon Sep 17 00:00:00 2001 From: DanConwayDev Date: Thu, 20 Nov 2025 21:36:09 +0000 Subject: replace actix with hyper --- Cargo.lock | 648 +++++++------------------------------------------- Cargo.toml | 9 +- src/http/landing.rs | 35 +-- src/http/mod.rs | 142 +++++++++-- src/http/websocket.rs | 73 ------ 5 files changed, 226 insertions(+), 681 deletions(-) delete mode 100644 src/http/websocket.rs diff --git a/Cargo.lock b/Cargo.lock index f316115..71490b2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,209 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "actix-codec" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f7b0a21988c1bf877cf4759ef5ddaac04c1c9fe808c9142ecb78ba97d97a28a" -dependencies = [ - "bitflags", - "bytes", - "futures-core", - "futures-sink", - "memchr", - "pin-project-lite", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "actix-http" -version = "3.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7926860314cbe2fb5d1f13731e387ab43bd32bca224e82e6e2db85de0a3dba49" -dependencies = [ - "actix-codec", - "actix-rt", - "actix-service", - "actix-utils", - "base64", - "bitflags", - "brotli", - "bytes", - "bytestring", - "derive_more", - "encoding_rs", - "flate2", - "foldhash", - "futures-core", - "h2", - "http 0.2.12", - "httparse", - "httpdate", - "itoa", - "language-tags", - "local-channel", - "mime", - "percent-encoding", - "pin-project-lite", - "rand 0.9.2", - "sha1", - "smallvec", - "tokio", - "tokio-util", - "tracing", - "zstd", -] - -[[package]] -name = "actix-macros" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" -dependencies = [ - "quote", - "syn", -] - -[[package]] -name = "actix-router" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13d324164c51f63867b57e73ba5936ea151b8a41a1d23d1031eeb9f70d0236f8" -dependencies = [ - "bytestring", - "cfg-if", - "http 0.2.12", - "regex", - "regex-lite", - "serde", - "tracing", -] - -[[package]] -name = "actix-rt" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92589714878ca59a7626ea19734f0e07a6a875197eec751bb5d3f99e64998c63" -dependencies = [ - "futures-core", - "tokio", -] - -[[package]] -name = "actix-server" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a65064ea4a457eaf07f2fba30b4c695bf43b721790e9530d26cb6f9019ff7502" -dependencies = [ - "actix-rt", - "actix-service", - "actix-utils", - "futures-core", - "futures-util", - "mio", - "socket2 0.5.10", - "tokio", - "tracing", -] - -[[package]] -name = "actix-service" -version = "2.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e46f36bf0e5af44bdc4bdb36fbbd421aa98c79a9bce724e1edeb3894e10dc7f" -dependencies = [ - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "actix-utils" -version = "3.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88a1dcdff1466e3c2488e1cb5c36a71822750ad43839937f85d2f4d9f8b705d8" -dependencies = [ - "local-waker", - "pin-project-lite", -] - -[[package]] -name = "actix-web" -version = "4.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2233f53f6cb18ae038ce1f0713ca0c72ca0c4b71fe9aaeb59924ce2c89c6dd85" -dependencies = [ - "actix-codec", - "actix-http", - "actix-macros", - "actix-router", - "actix-rt", - "actix-server", - "actix-service", - "actix-utils", - "actix-web-codegen", - "bytes", - "bytestring", - "cfg-if", - "cookie", - "derive_more", - "encoding_rs", - "foldhash", - "futures-core", - "futures-util", - "impl-more", - "itoa", - "language-tags", - "log", - "mime", - "once_cell", - "pin-project-lite", - "regex", - "regex-lite", - "serde", - "serde_json", - "serde_urlencoded", - "smallvec", - "socket2 0.6.1", - "time", - "tracing", - "url", -] - -[[package]] -name = "actix-web-codegen" -version = "4.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f591380e2e68490b5dfaf1dd1aa0ebe78d84ba7067078512b4ea6e4492d622b8" -dependencies = [ - "actix-router", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "actix-ws" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3a1fb4f9f2794b0aadaf2ba5f14a6f034c7e86957b458c506a8cb75953f2d99" -dependencies = [ - "actix-codec", - "actix-http", - "actix-web", - "bytestring", - "futures-core", - "tokio", -] - -[[package]] -name = "adler2" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" - [[package]] name = "aead" version = "0.5.2" @@ -224,21 +21,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "alloc-no-stdlib" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" - -[[package]] -name = "alloc-stdlib" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" -dependencies = [ - "alloc-no-stdlib", -] - [[package]] name = "android_system_properties" version = "0.1.5" @@ -357,7 +139,7 @@ dependencies = [ "tokio", "tokio-rustls", "tokio-socks", - "tokio-tungstenite 0.26.2", + "tokio-tungstenite", "url", "wasm-bindgen", "web-sys", @@ -369,6 +151,12 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef49f5882e4b6afaac09ad239a4f8c70a24b8f2b0897edb1f706008efd109cf4" +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "autocfg" version = "1.5.0" @@ -461,27 +249,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "brotli" -version = "8.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bd8b9603c7aa97359dbd97ecf258968c95f3adddd6db2f7e7a5bef101c84560" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", - "brotli-decompressor", -] - -[[package]] -name = "brotli-decompressor" -version = "5.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", -] - [[package]] name = "bumpalo" version = "3.19.0" @@ -494,15 +261,6 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" -[[package]] -name = "bytestring" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "113b4343b5f6617e7ad401ced8de3cc8b012e73a594347c307b90db3e9271289" -dependencies = [ - "bytes", -] - [[package]] name = "cbc" version = "0.1.2" @@ -519,8 +277,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37521ac7aabe3d13122dc382493e20c9416f299d2ccd5b3a5340a2570cdeb0f3" dependencies = [ "find-msvc-tools", - "jobserver", - "libc", "shlex", ] @@ -624,17 +380,6 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" -[[package]] -name = "cookie" -version = "0.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" -dependencies = [ - "percent-encoding", - "time", - "version_check", -] - [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -650,15 +395,6 @@ dependencies = [ "libc", ] -[[package]] -name = "crc32fast" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" -dependencies = [ - "cfg-if", -] - [[package]] name = "crypto-common" version = "0.1.6" @@ -676,36 +412,6 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" -[[package]] -name = "deranged" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587" -dependencies = [ - "powerfmt", -] - -[[package]] -name = "derive_more" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" -dependencies = [ - "derive_more-impl", -] - -[[package]] -name = "derive_more-impl" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "unicode-xid", -] - [[package]] name = "digest" version = "0.10.7" @@ -740,15 +446,6 @@ version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" -[[package]] -name = "encoding_rs" -version = "0.8.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" -dependencies = [ - "cfg-if", -] - [[package]] name = "equivalent" version = "1.0.2" @@ -761,28 +458,12 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127" -[[package]] -name = "flate2" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "foldhash" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" - [[package]] name = "form_urlencoded" version = "1.2.2" @@ -949,16 +630,16 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.27" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0beca50380b1fc32983fc1cb4587bfa4bb9e78fc259aad4a0032d2080309222d" +checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386" dependencies = [ + "atomic-waker", "bytes", "fnv", "futures-core", "futures-sink", - "futures-util", - "http 0.2.12", + "http", "indexmap", "slab", "tokio", @@ -1010,9 +691,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.12" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" dependencies = [ "bytes", "fnv", @@ -1020,14 +701,26 @@ dependencies = [ ] [[package]] -name = "http" -version = "1.3.1" +name = "http-body" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "fnv", - "itoa", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", ] [[package]] @@ -1042,6 +735,44 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +[[package]] +name = "hyper" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "pin-utils", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-util" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52e9a2a24dc5c6821e71a7030e1e14b7b632acac55c40e9d2e082c621261bb56" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "hyper", + "pin-project-lite", + "tokio", +] + [[package]] name = "iana-time-zone" version = "0.1.64" @@ -1168,12 +899,6 @@ dependencies = [ "icu_properties", ] -[[package]] -name = "impl-more" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8a5a9a0ff0086c7a148acb942baaabeadf9504d10400b5a05645853729b9cd2" - [[package]] name = "indexmap" version = "2.12.0" @@ -1218,16 +943,6 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" -[[package]] -name = "jobserver" -version = "0.1.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" -dependencies = [ - "getrandom 0.3.4", - "libc", -] - [[package]] name = "js-sys" version = "0.3.82" @@ -1238,12 +953,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "language-tags" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388" - [[package]] name = "lazy_static" version = "1.5.0" @@ -1262,23 +971,6 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" -[[package]] -name = "local-channel" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6cbc85e69b8df4b8bb8b89ec634e7189099cea8927a276b7384ce5488e53ec8" -dependencies = [ - "futures-core", - "futures-sink", - "local-waker", -] - -[[package]] -name = "local-waker" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d873d7c67ce09b42110d801813efbc9364414e356be9935700d368351657487" - [[package]] name = "lock_api" version = "0.4.14" @@ -1315,22 +1007,6 @@ version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - -[[package]] -name = "miniz_oxide" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" -dependencies = [ - "adler2", - "simd-adler32", -] - [[package]] name = "mio" version = "1.1.0" @@ -1338,7 +1014,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69d83b0086dc8ecf3ce9ae2874b2d1290252e2a30720bea58a5c6639b0092873" dependencies = [ "libc", - "log", "wasi", "windows-sys 0.61.2", ] @@ -1353,12 +1028,14 @@ checksum = "f0efe882e02d206d8d279c20eb40e03baf7cb5136a1476dc084a324fbc3ec42d" name = "ngit-grasp" version = "0.1.0" dependencies = [ - "actix-web", - "actix-ws", "anyhow", + "base64", "dotenvy", "futures-util", "grasp-audit", + "http-body-util", + "hyper", + "hyper-util", "nostr-relay-builder", "nostr-sdk 0.44.1", "serde", @@ -1366,7 +1043,6 @@ dependencies = [ "thiserror 1.0.69", "tokio", "tokio-test", - "tokio-tungstenite 0.28.0", "tracing", "tracing-subscriber", "url", @@ -1539,12 +1215,6 @@ dependencies = [ "windows-sys 0.61.2", ] -[[package]] -name = "num-conv" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" - [[package]] name = "num-traits" version = "0.2.19" @@ -1634,12 +1304,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "pkg-config" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" - [[package]] name = "poly1305" version = "0.8.0" @@ -1660,12 +1324,6 @@ dependencies = [ "zerovec", ] -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - [[package]] name = "ppv-lite86" version = "0.2.21" @@ -1767,18 +1425,6 @@ dependencies = [ "bitflags", ] -[[package]] -name = "regex" -version = "1.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - [[package]] name = "regex-automata" version = "0.4.13" @@ -1790,12 +1436,6 @@ dependencies = [ "regex-syntax", ] -[[package]] -name = "regex-lite" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d942b98df5e658f56f20d592c7f868833fe38115e65c33003d8cd224b0155da" - [[package]] name = "regex-syntax" version = "0.8.8" @@ -1952,18 +1592,6 @@ dependencies = [ "serde_core", ] -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - [[package]] name = "sha1" version = "0.10.6" @@ -2010,12 +1638,6 @@ dependencies = [ "libc", ] -[[package]] -name = "simd-adler32" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" - [[package]] name = "slab" version = "0.4.11" @@ -2028,16 +1650,6 @@ version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" -[[package]] -name = "socket2" -version = "0.5.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - [[package]] name = "socket2" version = "0.6.1" @@ -2137,37 +1749,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "time" -version = "0.3.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" -dependencies = [ - "deranged", - "itoa", - "num-conv", - "powerfmt", - "serde", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" - -[[package]] -name = "time-macros" -version = "0.2.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" -dependencies = [ - "num-conv", - "time-core", -] - [[package]] name = "tinystr" version = "0.8.2" @@ -2205,7 +1786,7 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.6.1", + "socket2", "tokio-macros", "windows-sys 0.61.2", ] @@ -2279,22 +1860,10 @@ dependencies = [ "rustls-pki-types", "tokio", "tokio-rustls", - "tungstenite 0.26.2", + "tungstenite", "webpki-roots 0.26.11", ] -[[package]] -name = "tokio-tungstenite" -version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d25a406cddcc431a75d3d9afc6a7c0f7428d4891dd973e4d54c56b46127bf857" -dependencies = [ - "futures-util", - "log", - "tokio", - "tungstenite 0.28.0", -] - [[package]] name = "tokio-util" version = "0.7.17" @@ -2314,7 +1883,6 @@ version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ - "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -2370,6 +1938,12 @@ dependencies = [ "tracing-log", ] +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + [[package]] name = "tungstenite" version = "0.26.2" @@ -2378,7 +1952,7 @@ checksum = "4793cb5e56680ecbb1d843515b23b6de9a75eb04b66643e256a396d43be33c13" dependencies = [ "bytes", "data-encoding", - "http 1.3.1", + "http", "httparse", "log", "rand 0.9.2", @@ -2389,23 +1963,6 @@ dependencies = [ "utf-8", ] -[[package]] -name = "tungstenite" -version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8628dcc84e5a09eb3d8423d6cb682965dea9133204e8fb3efee74c2a0c259442" -dependencies = [ - "bytes", - "data-encoding", - "http 1.3.1", - "httparse", - "log", - "rand 0.9.2", - "sha1", - "thiserror 2.0.17", - "utf-8", -] - [[package]] name = "typenum" version = "1.19.0" @@ -2427,12 +1984,6 @@ dependencies = [ "tinyvec", ] -[[package]] -name = "unicode-xid" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" - [[package]] name = "universal-hash" version = "0.5.1" @@ -2502,6 +2053,15 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + [[package]] name = "wasi" version = "0.11.1+wasi-snapshot-preview1" @@ -2932,31 +2492,3 @@ dependencies = [ "quote", "syn", ] - -[[package]] -name = "zstd" -version = "0.13.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" -dependencies = [ - "zstd-safe", -] - -[[package]] -name = "zstd-safe" -version = "7.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" -dependencies = [ - "zstd-sys", -] - -[[package]] -name = "zstd-sys" -version = "2.0.16+zstd.1.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748" -dependencies = [ - "cc", - "pkg-config", -] diff --git a/Cargo.toml b/Cargo.toml index ae84241..c26247c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,9 +11,10 @@ repository = "https://gitworkshop.dev/ngit-grasp" # Async runtime tokio = { version = "1.35", features = ["full"] } -# HTTP server -actix-web = "4.4" -actix-ws = "0.3" +# HTTP server (hyper for relay integration) +hyper = { version = "1.4", features = ["full"] } +hyper-util = { version = "0.1", features = ["tokio", "server", "http1", "http2"] } +http-body-util = "0.1" # Nostr relay nostr-relay-builder = "0.44" @@ -23,6 +24,7 @@ nostr-sdk = "0.44" # Utilities futures-util = "0.3" +base64 = "0.22" # Serialization serde = { version = "1.0", features = ["derive"] } @@ -38,7 +40,6 @@ dotenvy = "0.15" # Error handling anyhow = "1.0" thiserror = "1.0" -tokio-tungstenite = "0.28.0" # Git (for future use) # git-http-backend = "0.3" diff --git a/src/http/landing.rs b/src/http/landing.rs index 976ec50..55ffb26 100644 --- a/src/http/landing.rs +++ b/src/http/landing.rs @@ -1,40 +1,15 @@ /// Landing Page Handler /// -/// Serves the HTML landing page or upgrades to WebSocket for Nostr relay connections. -use actix_web::{web, HttpRequest, HttpResponse, Result}; -use nostr_relay_builder::LocalRelay; - +/// Generates HTML landing page for the Nostr relay. use crate::config::Config; -/// Handle landing page or WebSocket upgrade -pub async fn handle( - req: HttpRequest, - stream: web::Payload, - config: web::Data, - relay: web::Data, -) -> Result { - // Check if this is a WebSocket upgrade request - if let Some(upgrade) = req.headers().get("upgrade") { - if upgrade - .to_str() - .unwrap_or("") - .eq_ignore_ascii_case("websocket") - { - // Delegate to WebSocket handler - return crate::http::websocket::handle(req, stream, relay).await; - } - } - - // Otherwise, serve the landing page - let html = format!( +/// Generate the HTML landing page +pub fn get_html(config: &Config) -> String { + format!( include_str!("../../templates/landing.html"), relay_name = config.relay_name, relay_description = config.relay_description, domain = config.domain, bind_address = config.bind_address, - ); - - Ok(HttpResponse::Ok() - .content_type("text/html; charset=utf-8") - .body(html)) + ) } diff --git a/src/http/mod.rs b/src/http/mod.rs index b434c69..4690790 100644 --- a/src/http/mod.rs +++ b/src/http/mod.rs @@ -1,30 +1,140 @@ /// HTTP Server Module /// -/// Provides actix-web HTTP server with WebSocket upgrade support for the Nostr relay. +/// Provides hyper HTTP server with WebSocket upgrade support for the Nostr relay. pub mod landing; -pub mod websocket; -use actix_web::{middleware, web, App, HttpServer}; +use std::future::Future; +use std::net::SocketAddr; +use std::pin::Pin; + +use hyper::body::Incoming; +use hyper::header::{CONNECTION, SEC_WEBSOCKET_ACCEPT, UPGRADE}; +use hyper::server::conn::http1; +use hyper::service::Service; +use hyper::{Request, Response}; +use hyper_util::rt::TokioIo; +use nostr_sdk::hashes::sha1::Hash as Sha1Hash; +use nostr_sdk::hashes::{Hash, HashEngine}; use nostr_relay_builder::LocalRelay; +use tokio::net::TcpListener; +use base64::Engine; use crate::config::Config; +/// HTTP Service that serves both WebSocket (relay) and HTML landing page +struct HttpService { + relay: LocalRelay, + config: Config, + remote: SocketAddr, +} + +impl HttpService { + fn new(relay: LocalRelay, config: Config, remote: SocketAddr) -> Self { + Self { + relay, + config, + remote, + } + } +} + +impl Service> for HttpService { + type Response = Response; + type Error = String; + type Future = Pin> + Send>>; + + fn call(&self, req: Request) -> Self::Future { + let base = Response::builder().header("server", "ngit-grasp"); + + // Check if this is a WebSocket upgrade request + if let (Some(c), Some(w)) = ( + req.headers().get("connection"), + req.headers().get("upgrade"), + ) { + if c.to_str() + .map(|s| s.to_lowercase() == "upgrade") + .unwrap_or(false) + && w.to_str() + .map(|s| s.to_lowercase() == "websocket") + .unwrap_or(false) + { + let key = req.headers().get("sec-websocket-key"); + let derived = key.map(|k| derive_accept_key(k.as_bytes())); + + let addr = self.remote; + let relay = self.relay.clone(); + + tokio::spawn(async move { + match hyper::upgrade::on(req).await { + Ok(upgraded) => { + tracing::info!("WebSocket connection established from {}", addr); + if let Err(e) = relay.take_connection(TokioIo::new(upgraded), addr).await + { + tracing::error!("Relay error for {}: {}", addr, e); + } + tracing::info!("WebSocket connection closed for {}", addr); + } + Err(e) => tracing::error!("Upgrade error: {}", e), + } + }); + + return Box::pin(async move { + Ok(base + .status(101) + .header(CONNECTION, "upgrade") + .header(UPGRADE, "websocket") + .header(SEC_WEBSOCKET_ACCEPT, derived.unwrap()) + .body("".to_string()) + .unwrap()) + }); + } + } + + // Serve landing page for HTTP requests + let html = landing::get_html(&self.config); + Box::pin(async move { + Ok(base + .status(200) + .header("content-type", "text/html; charset=utf-8") + .body(html) + .unwrap()) + }) + } +} + +/// Derive the `Sec-WebSocket-Accept` response header from a `Sec-WebSocket-Key` request header +fn derive_accept_key(request_key: &[u8]) -> String { + const WS_GUID: &[u8] = b"258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; + let mut engine = Sha1Hash::engine(); + engine.input(request_key); + engine.input(WS_GUID); + let hash: Sha1Hash = Sha1Hash::from_engine(engine); + base64::prelude::BASE64_STANDARD.encode(hash) +} + /// Start the HTTP server with integrated Nostr relay pub async fn run_server(config: Config, relay: LocalRelay) -> anyhow::Result<()> { - let bind_addr = config.bind_address.clone(); + let bind_addr: SocketAddr = config.bind_address.parse()?; tracing::info!("Starting HTTP server on {}", bind_addr); + tracing::info!("Relay name: {}", config.relay_name); + tracing::info!("Domain: {}", config.domain); - HttpServer::new(move || { - App::new() - .app_data(web::Data::new(config.clone())) - .app_data(web::Data::new(relay.clone())) - .wrap(middleware::Logger::default()) - .route("/", web::get().to(landing::handle)) - }) - .bind(&bind_addr)? - .run() - .await?; - - Ok(()) + let listener = TcpListener::bind(&bind_addr).await?; + + loop { + let (socket, addr) = listener.accept().await?; + let io = TokioIo::new(socket); + let service = HttpService::new(relay.clone(), config.clone(), addr); + + tokio::spawn(async move { + if let Err(e) = http1::Builder::new() + .serve_connection(io, service) + .with_upgrades() + .await + { + tracing::error!("Failed to handle request from {}: {}", addr, e); + } + }); + } } diff --git a/src/http/websocket.rs b/src/http/websocket.rs deleted file mode 100644 index 0171013..0000000 --- a/src/http/websocket.rs +++ /dev/null @@ -1,73 +0,0 @@ -/// WebSocket Handler -/// -/// Handles WebSocket upgrade requests and passes connections to the Nostr relay. -use actix_web::{web, Error, HttpRequest, HttpResponse, Result}; -use actix_ws::Message; -use futures_util::StreamExt; -use nostr_relay_builder::LocalRelay; - -/// Handle WebSocket upgrade and relay connection -pub async fn handle( - req: HttpRequest, - stream: web::Payload, - relay: web::Data, -) -> Result { - let (response, mut session, mut msg_stream) = actix_ws::handle(&req, stream)?; - - let peer_addr = req - .peer_addr() - .unwrap_or_else(|| "0.0.0.0:0".parse().unwrap()); - - tracing::debug!("WebSocket connection from {}", peer_addr); - - // Spawn task to handle the WebSocket connection - // TODO: Will use relay.take_connection() for full Nostr relay integration - let _relay = relay.get_ref().clone(); - actix_web::rt::spawn(async move { - // Create a channel to communicate between actix-ws and relay - let (tx, mut rx) = tokio::sync::mpsc::unbounded_channel(); - - // Spawn task to send messages from relay to client - let mut session_clone = session.clone(); - actix_web::rt::spawn(async move { - while let Some(msg) = rx.recv().await { - if session_clone.text(msg).await.is_err() { - break; - } - } - }); - - // Handle incoming messages from client - while let Some(Ok(msg)) = msg_stream.next().await { - match msg { - Message::Text(text) => { - // For now, just echo back - will integrate with relay in next phase - tracing::debug!("Received text message: {}", text); - if let Err(e) = tx.send(text.to_string()) { - tracing::error!("Failed to send message: {}", e); - break; - } - } - Message::Binary(_) => { - tracing::warn!("Received unexpected binary message"); - } - Message::Close(_) => { - tracing::debug!("Client closed connection"); - break; - } - Message::Ping(bytes) => { - if session.pong(&bytes).await.is_err() { - break; - } - } - Message::Pong(_) => {} - Message::Continuation(_) => {} - Message::Nop => {} - } - } - - tracing::debug!("WebSocket connection closed for {}", peer_addr); - }); - - Ok(response) -} -- cgit v1.2.3