diff --git a/Cargo.lock b/Cargo.lock index b8b2d2d..dbb725b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -64,6 +64,12 @@ dependencies = [ "critical-section", ] +[[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.3.0" @@ -198,6 +204,12 @@ dependencies = [ "serde", ] +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + [[package]] name = "bitflags" version = "2.6.0" @@ -305,9 +317,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4934e6b7e8419148b6ef56950d277af8561060b56afd59e2aadf98b59fce6baa" dependencies = [ "cookie", - "idna", + "idna 0.5.0", "indexmap", "log", + "publicsuffix", "serde", "serde_derive", "serde_json", @@ -315,6 +328,22 @@ dependencies = [ "url", ] +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + [[package]] name = "cpufeatures" version = "0.2.12" @@ -511,12 +540,37 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" +[[package]] +name = "encoding_rs" +version = "0.8.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" +dependencies = [ + "cfg-if", +] + [[package]] name = "equivalent" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "fastrand" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" + [[package]] name = "fiat-crypto" version = "0.2.9" @@ -551,6 +605,21 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -678,6 +747,25 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +[[package]] +name = "h2" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "hash32" version = "0.2.1" @@ -737,7 +825,7 @@ version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2bc30da4a93ff8cb98e535d595d6de42731d4719d707bc1c86f579158751a24e" dependencies = [ - "bitflags", + "bitflags 2.6.0", "byteorder", "heed-traits", "heed-types", @@ -830,6 +918,7 @@ dependencies = [ "bytes", "futures-channel", "futures-util", + "h2", "http", "http-body", "httparse", @@ -838,6 +927,40 @@ dependencies = [ "pin-project-lite", "smallvec", "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155" +dependencies = [ + "futures-util", + "http", + "hyper", + "hyper-util", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", +] + +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", ] [[package]] @@ -847,12 +970,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ab92f4f49ee4fb4f997c784b7a2e0fa70050211e0b6a287f898c3c9785ca956" dependencies = [ "bytes", + "futures-channel", "futures-util", "http", "http-body", "hyper", "pin-project-lite", + "socket2", "tokio", + "tower", + "tower-service", + "tracing", +] + +[[package]] +name = "idna" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", ] [[package]] @@ -875,6 +1013,12 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + [[package]] name = "itoa" version = "1.0.11" @@ -908,10 +1052,16 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags", + "bitflags 2.6.0", "libc", ] +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + [[package]] name = "litrs" version = "0.4.1" @@ -1027,6 +1177,23 @@ dependencies = [ "getrandom", ] +[[package]] +name = "native-tls" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -1068,6 +1235,50 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[package]] +name = "openssl" +version = "0.10.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" +dependencies = [ + "bitflags 2.6.0", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "overload" version = "0.1.1" @@ -1223,6 +1434,12 @@ dependencies = [ "spki", ] +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + [[package]] name = "postcard" version = "1.0.8" @@ -1256,6 +1473,12 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "psl-types" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac" + [[package]] name = "pubky" version = "0.1.0" @@ -1267,6 +1490,7 @@ dependencies = [ "pkarr", "pubky-common", "pubky_homeserver", + "reqwest", "thiserror", "tokio", "ureq", @@ -1316,6 +1540,16 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "publicsuffix" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96a8c1bda5ae1af7f99a2962e49df150414a43d62404644d98dd5c3a93d07457" +dependencies = [ + "idna 0.3.0", + "psl-types", +] + [[package]] name = "quote" version = "1.0.36" @@ -1361,7 +1595,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd" dependencies = [ - "bitflags", + "bitflags 2.6.0", ] [[package]] @@ -1419,6 +1653,51 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +[[package]] +name = "reqwest" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7d6d2a27d57148378eb5e111173f4276ad26340ecc5c49a4a2152167a2d6a37" +dependencies = [ + "base64 0.22.1", + "bytes", + "cookie", + "cookie_store", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-tls", + "hyper-util", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper 1.0.1", + "system-configuration", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + [[package]] name = "ring" version = "0.17.8" @@ -1449,6 +1728,19 @@ dependencies = [ "semver", ] +[[package]] +name = "rustix" +version = "0.38.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +dependencies = [ + "bitflags 2.6.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + [[package]] name = "rustls" version = "0.23.11" @@ -1464,6 +1756,16 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rustls-pemfile" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" +dependencies = [ + "base64 0.22.1", + "rustls-pki-types", +] + [[package]] name = "rustls-pki-types" version = "1.7.0" @@ -1493,6 +1795,15 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +[[package]] +name = "schannel" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +dependencies = [ + "windows-sys 0.52.0", +] + [[package]] name = "scoped-tls" version = "1.0.1" @@ -1505,6 +1816,29 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +dependencies = [ + "bitflags 2.6.0", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "self_cell" version = "1.0.4" @@ -1650,7 +1984,7 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01607fe2e61894468c6dc0b26103abb073fb08b79a3d9e4b6d76a1a341549958" dependencies = [ - "bitflags", + "bitflags 2.6.0", ] [[package]] @@ -1747,6 +2081,39 @@ dependencies = [ "crossbeam-queue", ] +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tempfile" +version = "3.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +dependencies = [ + "cfg-if", + "fastrand", + "rustix", + "windows-sys 0.52.0", +] + [[package]] name = "thiserror" version = "1.0.62" @@ -1853,6 +2220,27 @@ dependencies = [ "syn", ] +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" +dependencies = [ + "rustls", + "rustls-pki-types", + "tokio", +] + [[package]] name = "tokio-util" version = "0.7.11" @@ -1905,7 +2293,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" dependencies = [ - "bitflags", + "bitflags 2.6.0", "bytes", "http", "http-body", @@ -1990,6 +2378,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 = "typenum" version = "1.17.0" @@ -2048,7 +2442,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" dependencies = [ "form_urlencoded", - "idna", + "idna 0.5.0", "percent-encoding", ] @@ -2058,12 +2452,27 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[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.0+wasi-snapshot-preview1" @@ -2341,6 +2750,16 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "winreg" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + [[package]] name = "z32" version = "1.1.1" diff --git a/pubky/Cargo.toml b/pubky/Cargo.toml index 8408c39..758af8e 100644 --- a/pubky/Cargo.toml +++ b/pubky/Cargo.toml @@ -15,6 +15,7 @@ pkarr = "2.1.0" thiserror = "1.0.62" wasm-bindgen = "0.2.92" url = "2.5.2" +reqwest = { version = "0.12.5", features = ["cookies"] } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] pubky-common = { version = "0.1.0", path = "../pubky-common" } diff --git a/pubky/src/client.rs b/pubky/src/client.rs index 63fae96..2839110 100644 --- a/pubky/src/client.rs +++ b/pubky/src/client.rs @@ -1,33 +1,42 @@ mod auth; mod pkarr; -mod public; +// mod public; use std::{collections::HashMap, fmt::format, time::Duration}; -use ureq::{Agent, Response}; +use ::pkarr::PkarrClientAsync; use url::Url; use pkarr::{DhtSettings, PkarrClient, Settings, Testnet}; use crate::error::{Error, Result}; +static DEFAULT_USER_AGENT: &str = concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION"),); + #[derive(Debug, Clone)] pub struct PubkyClient { - agent: Agent, - pkarr: PkarrClient, + http: reqwest::Client, + pkarr: PkarrClientAsync, } impl PubkyClient { pub fn new() -> Self { Self { - agent: Agent::new(), - pkarr: PkarrClient::new(Default::default()).unwrap(), + http: reqwest::Client::builder() + .user_agent(DEFAULT_USER_AGENT) + .build() + .unwrap(), + pkarr: PkarrClient::new(Default::default()).unwrap().as_async(), } } pub fn test(testnet: &Testnet) -> Self { Self { - agent: Agent::new(), + http: reqwest::Client::builder() + .cookie_store(true) + .user_agent(DEFAULT_USER_AGENT) + .build() + .unwrap(), pkarr: PkarrClient::new(Settings { dht: DhtSettings { request_timeout: Some(Duration::from_millis(10)), @@ -36,15 +45,10 @@ impl PubkyClient { }, ..Settings::default() }) - .unwrap(), + .unwrap() + .as_async(), } } - - // === Private Methods === - - fn request(&self, method: HttpMethod, url: &Url) -> ureq::Request { - self.agent.request_url(method.into(), url) - } } impl Default for PubkyClient { @@ -52,22 +56,3 @@ impl Default for PubkyClient { Self::new() } } - -#[derive(Debug, Clone)] -pub enum HttpMethod { - Get, - Put, - Post, - Delete, -} - -impl From for &str { - fn from(value: HttpMethod) -> Self { - match value { - HttpMethod::Get => "GET", - HttpMethod::Put => "PUT", - HttpMethod::Post => "POST", - HttpMethod::Delete => "DELETE", - } - } -} diff --git a/pubky/src/client/auth.rs b/pubky/src/client/auth.rs index b1f4cc8..c99a451 100644 --- a/pubky/src/client/auth.rs +++ b/pubky/src/client/auth.rs @@ -1,23 +1,27 @@ -use pkarr::{Keypair, PublicKey}; +use reqwest::StatusCode; +use pkarr::{Keypair, PublicKey}; use pubky_common::{auth::AuthnSignature, session::Session}; -use super::{Error, HttpMethod, PubkyClient, Result}; +use super::{Error, PubkyClient, Result}; impl PubkyClient { /// Signup to a homeserver and update Pkarr accordingly. /// /// The homeserver is a Pkarr domain name, where the TLD is a Pkarr public key /// for example "pubky.o4dksfbqk85ogzdb5osziw6befigbuxmuxkuxq8434q89uj56uyy" - pub fn signup(&self, keypair: &Keypair, homeserver: &str) -> Result<()> { - let (audience, mut url) = self.resolve_endpoint(homeserver)?; + pub async fn signup(&self, keypair: &Keypair, homeserver: &str) -> Result<()> { + let (audience, mut url) = self.resolve_endpoint(homeserver).await?; url.set_path(&format!("/{}", keypair.public_key())); - self.request(HttpMethod::Put, &url) - .send_bytes(AuthnSignature::generate(keypair, &audience).as_bytes())?; + let body = AuthnSignature::generate(keypair, &audience) + .as_bytes() + .to_owned(); - self.publish_pubky_homeserver(keypair, homeserver); + self.http.put(url).body(body).send().await?; + + self.publish_pubky_homeserver(keypair, homeserver).await?; Ok(()) } @@ -26,52 +30,50 @@ impl PubkyClient { /// /// Returns an [Error::NotSignedIn] if so, or [ureq::Error] if /// the response has any other `>=400` status code. - pub fn session(&self, pubky: &PublicKey) -> Result { - let (homeserver, mut url) = self.resolve_pubky_homeserver(pubky)?; + pub async fn session(&self, pubky: &PublicKey) -> Result { + let (homeserver, mut url) = self.resolve_pubky_homeserver(pubky).await?; url.set_path(&format!("/{}/session", pubky)); - let mut bytes = vec![]; + let res = self.http.get(url).send().await?; - let result = self.request(HttpMethod::Get, &url).call().map_err(Box::new); + if res.status() == StatusCode::NOT_FOUND { + return Err(Error::NotSignedIn); + } - let reader = self.request(HttpMethod::Get, &url).call().map_err(|err| { - match err { - ureq::Error::Status(404, _) => Error::NotSignedIn, - // TODO: handle other types of errors - _ => err.into(), - } - })?; + if !res.status().is_success() { + res.error_for_status_ref()?; + }; - reader.into_reader().read_to_end(&mut bytes); + let bytes = res.bytes().await?; Ok(Session::deserialize(&bytes)?) } /// Signout from a homeserver. - pub fn signout(&self, pubky: &PublicKey) -> Result<()> { - let (homeserver, mut url) = self.resolve_pubky_homeserver(pubky)?; + pub async fn signout(&self, pubky: &PublicKey) -> Result<()> { + let (homeserver, mut url) = self.resolve_pubky_homeserver(pubky).await?; url.set_path(&format!("/{}/session", pubky)); - self.request(HttpMethod::Delete, &url) - .call() - .map_err(Box::new)?; + self.http.delete(url).send().await?; Ok(()) } /// Signin to a homeserver. - pub fn signin(&self, keypair: &Keypair) -> Result<()> { + pub async fn signin(&self, keypair: &Keypair) -> Result<()> { let pubky = keypair.public_key(); - let (audience, mut url) = self.resolve_pubky_homeserver(&pubky)?; + let (audience, mut url) = self.resolve_pubky_homeserver(&pubky).await?; url.set_path(&format!("/{}/session", &pubky)); - self.request(HttpMethod::Post, &url) - .send_bytes(AuthnSignature::generate(keypair, &audience).as_bytes()) - .map_err(Box::new)?; + let body = AuthnSignature::generate(keypair, &audience) + .as_bytes() + .to_owned(); + + self.http.post(url).body(body).send().await?; Ok(()) } @@ -90,7 +92,7 @@ mod tests { let testnet = Testnet::new(3); let server = Homeserver::start_test(&testnet).await.unwrap(); - let client = PubkyClient::test(&testnet).as_async(); + let client = PubkyClient::test(&testnet); let keypair = Keypair::random(); diff --git a/pubky/src/client/pkarr.rs b/pubky/src/client/pkarr.rs index a568c4c..f22ae43 100644 --- a/pubky/src/client/pkarr.rs +++ b/pubky/src/client/pkarr.rs @@ -10,26 +10,34 @@ use super::{Error, PubkyClient, Result, Url}; impl PubkyClient { /// Publish the SVCB record for `_pubky.`. - pub(crate) fn publish_pubky_homeserver(&self, keypair: &Keypair, host: &str) -> Result<()> { - let existing = self.pkarr.resolve(&keypair.public_key())?; + pub(crate) async fn publish_pubky_homeserver( + &self, + keypair: &Keypair, + host: &str, + ) -> Result<()> { + let existing = self.pkarr.resolve(&keypair.public_key()).await?; let signed_packet = prepare_packet_for_signup(keypair, host, existing)?; - self.pkarr.publish(&signed_packet)?; + self.pkarr.publish(&signed_packet).await?; Ok(()) } /// Resolve the homeserver for a pubky. - pub(crate) fn resolve_pubky_homeserver(&self, pubky: &PublicKey) -> Result<(PublicKey, Url)> { + pub(crate) async fn resolve_pubky_homeserver( + &self, + pubky: &PublicKey, + ) -> Result<(PublicKey, Url)> { let target = format!("_pubky.{}", pubky); self.resolve_endpoint(&target) + .await .map_err(|_| Error::Generic("Could not resolve homeserver".to_string())) } /// Resolve a service's public_key and clearnet url from a Pubky domain - pub(crate) fn resolve_endpoint(&self, target: &str) -> Result<(PublicKey, Url)> { + pub(crate) async fn resolve_endpoint(&self, target: &str) -> Result<(PublicKey, Url)> { // TODO: cache the result of this function? let mut target = target.to_string(); @@ -40,7 +48,7 @@ impl PubkyClient { // PublicKey is very good at extracting the Pkarr TLD from a string. while let Ok(public_key) = PublicKey::try_from(target.clone()) { - let response = self.pkarr.resolve(&public_key)?; + let response = self.pkarr.resolve(&public_key).await?; let done = parse_pubky_svcb( response, @@ -106,23 +114,24 @@ mod tests { pkarr_client.publish(&signed_packet).await.unwrap(); - tokio::task::spawn_blocking(move || { + { let client = PubkyClient::test(&testnet); let pubky = Keypair::random(); client - .publish_pubky_homeserver(&pubky, &format!("pubky.{}", &intermediate.public_key())); + .publish_pubky_homeserver(&pubky, &format!("pubky.{}", &intermediate.public_key())) + .await + .unwrap(); let (public_key, url) = client .resolve_pubky_homeserver(&pubky.public_key()) + .await .unwrap(); assert_eq!(public_key, server.public_key()); assert_eq!(url.host_str(), Some("localhost")); assert_eq!(url.port(), Some(server.port())); - }) - .await - .expect("task failed") + } } } diff --git a/pubky/src/client/public.rs b/pubky/src/client/public.rs index 68b8209..e2d396f 100644 --- a/pubky/src/client/public.rs +++ b/pubky/src/client/public.rs @@ -73,7 +73,7 @@ mod tests { let testnet = Testnet::new(3); let server = Homeserver::start_test(&testnet).await.unwrap(); - let client = PubkyClient::test(&testnet).as_async(); + let client = PubkyClient::test(&testnet); let keypair = Keypair::random(); diff --git a/pubky/src/client_async.rs b/pubky/src/client_async.rs deleted file mode 100644 index 6fa063e..0000000 --- a/pubky/src/client_async.rs +++ /dev/null @@ -1,94 +0,0 @@ -use std::thread; - -use bytes::Bytes; - -use pkarr::{Keypair, PublicKey}; -use pubky_common::session::Session; - -use crate::{client::PubkyClient, error::Result}; - -pub struct PubkyClientAsync(PubkyClient); - -impl PubkyClient { - pub fn as_async(&self) -> PubkyClientAsync { - PubkyClientAsync(self.clone()) - } -} - -impl PubkyClientAsync { - /// Async version of [PubkyClient::signup] - pub async fn signup(&self, keypair: &Keypair, homeserver: &str) -> Result<()> { - let (sender, receiver) = flume::bounded::>(1); - - let client = self.0.clone(); - let keypair = keypair.clone(); - let homeserver = homeserver.to_string(); - - thread::spawn(move || sender.send(client.signup(&keypair, &homeserver))); - - receiver.recv_async().await? - } - - /// Async version of [PubkyClient::session] - pub async fn session(&self, pubky: &PublicKey) -> Result { - let (sender, receiver) = flume::bounded::>(1); - - let client = self.0.clone(); - let pubky = pubky.clone(); - - thread::spawn(move || sender.send(client.session(&pubky))); - - receiver.recv_async().await? - } - - /// Async version of [PubkyClient::signout] - pub async fn signout(&self, pubky: &PublicKey) -> Result<()> { - let (sender, receiver) = flume::bounded::>(1); - - let client = self.0.clone(); - let pubky = pubky.clone(); - - thread::spawn(move || sender.send(client.signout(&pubky))); - - receiver.recv_async().await? - } - - /// Async version of [PubkyClient::signin] - pub async fn signin(&self, keypair: &Keypair) -> Result<()> { - let (sender, receiver) = flume::bounded::>(1); - - let client = self.0.clone(); - let keypair = keypair.clone(); - - thread::spawn(move || sender.send(client.signin(&keypair))); - - receiver.recv_async().await? - } - - /// Async version of [PubkyClient::put] - pub async fn put(&self, pubky: &PublicKey, path: &str, content: &[u8]) -> Result<()> { - let (sender, receiver) = flume::bounded::>(1); - - let client = self.0.clone(); - let pubky = pubky.clone(); - let path = path.to_string(); - let content = content.to_vec(); - - thread::spawn(move || sender.send(client.put(&pubky, &path, &content))); - - receiver.recv_async().await? - } - - /// Async version of [PubkyClient::get] - pub async fn get(&self, pubky: &PublicKey, path: &str) -> Result { - let (sender, receiver) = flume::bounded::>(1); - - let client = self.0.clone(); - let pubky = pubky.clone(); - let path = path.to_string(); - - thread::spawn(move || sender.send(client.get(&pubky, &path))); - - receiver.recv_async().await? - } -} diff --git a/pubky/src/error.rs b/pubky/src/error.rs index 2b5320e..398cb7b 100644 --- a/pubky/src/error.rs +++ b/pubky/src/error.rs @@ -30,17 +30,9 @@ pub enum Error { Flume(#[from] flume::RecvError), #[error(transparent)] - #[cfg(not(target_arch = "wasm32"))] - Ureq(#[from] Box), + Reqwest(#[from] reqwest::Error), #[error(transparent)] #[cfg(not(target_arch = "wasm32"))] Session(#[from] pubky_common::session::Error), } - -#[cfg(not(target_arch = "wasm32"))] -impl From for Error { - fn from(error: ureq::Error) -> Self { - Error::Ureq(Box::new(error)) - } -} diff --git a/pubky/src/lib.rs b/pubky/src/lib.rs index 91a117d..36ff2c0 100644 --- a/pubky/src/lib.rs +++ b/pubky/src/lib.rs @@ -16,7 +16,6 @@ macro_rules! if_wasm { if_not_wasm! { mod client; - mod client_async; use client::PubkyClient; } diff --git a/pubky/src/wasm.rs b/pubky/src/wasm.rs index 2414ba4..a8d438f 100644 --- a/pubky/src/wasm.rs +++ b/pubky/src/wasm.rs @@ -6,6 +6,7 @@ pub mod pkarr; #[wasm_bindgen] pub struct PubkyClient { + pub(crate) http: reqwest::Client, pub(crate) pkarr: pkarr::PkarrRelayClient, } @@ -14,6 +15,7 @@ impl PubkyClient { #[wasm_bindgen(constructor)] pub fn new() -> Self { Self { + http: reqwest::Client::new(), pkarr: pkarr::PkarrRelayClient::default(), } } diff --git a/pubky/src/wasm/auth.rs b/pubky/src/wasm/auth.rs index 6f03834..08b802d 100644 --- a/pubky/src/wasm/auth.rs +++ b/pubky/src/wasm/auth.rs @@ -13,50 +13,24 @@ impl PubkyClient { /// The homeserver is a Pkarr domain name, where the TLD is a Pkarr public key /// for example "pubky.o4dksfbqk85ogzdb5osziw6befigbuxmuxkuxq8434q89uj56uyy" #[wasm_bindgen] - pub async fn signup(&self, keypair: &Keypair, homeserver: &str) -> Result<(), JsError> { - // let (audience, mut url) = self.resolve_endpoint(homeserver)?; + pub async fn signup(&self, keypair: &Keypair, homeserver: &str) -> Result { + let (audience, mut url) = self.resolve_endpoint(homeserver)?; - // url.set_path(&format!("/{}", keypair.public_key())); + url.set_path(&format!("/{}", keypair.public_key())); - // let body = AuthnSignature::generate(keypair, &audience).as_bytes(); + self.http + .put(&url) + .send_bytes(AuthnSignature::generate(keypair, &audience).as_bytes())?; - // fetch_base(url.to_string(), "PUT", body).await?; - - self.publish_pubky_homeserver(keypair, homeserver).await?; + self.publish_pubky_homeserver(keypair, homeserver).await; Ok(()) } } -async fn fetch_base( - url: &String, - method: &str, - body: Option>, -) -> Result { - let mut opts = web_sys::RequestInit::new(); - opts.method(method); - opts.mode(RequestMode::Cors); - - if let Some(body) = body { - let body_bytes: &[u8] = &body; - let body_array: js_sys::Uint8Array = body_bytes.into(); - let js_value: &JsValue = body_array.as_ref(); - opts.body(Some(js_value)); - } - - let js_request = web_sys::Request::new_with_str_and_init(url, &opts)?; - - let window = web_sys::window().unwrap(); - let response = JsFuture::from(window.fetch_with_request(&js_request)).await?; - - let response: web_sys::Response = response.dyn_into()?; - - Ok(response) -} - #[cfg(test)] mod tests { - use wasm_bindgen_test::*; + use wasm_bindgen_test::wasm_bindgen_test; wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);