feat(pubky): use reqwest and async instead of ureq

This commit is contained in:
nazeh
2024-07-27 18:31:34 +03:00
parent c466ca5546
commit ba50429b7a
11 changed files with 509 additions and 220 deletions

433
Cargo.lock generated
View File

@@ -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"

View File

@@ -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" }

View File

@@ -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<HttpMethod> for &str {
fn from(value: HttpMethod) -> Self {
match value {
HttpMethod::Get => "GET",
HttpMethod::Put => "PUT",
HttpMethod::Post => "POST",
HttpMethod::Delete => "DELETE",
}
}
}

View File

@@ -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<Session> {
let (homeserver, mut url) = self.resolve_pubky_homeserver(pubky)?;
pub async fn session(&self, pubky: &PublicKey) -> Result<Session> {
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();

View File

@@ -10,26 +10,34 @@ use super::{Error, PubkyClient, Result, Url};
impl PubkyClient {
/// Publish the SVCB record for `_pubky.<public_key>`.
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")
}
}
}

View File

@@ -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();

View File

@@ -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::<Result<()>>(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<Session> {
let (sender, receiver) = flume::bounded::<Result<Session>>(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::<Result<()>>(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::<Result<()>>(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::<Result<()>>(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<Bytes> {
let (sender, receiver) = flume::bounded::<Result<Bytes>>(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?
}
}

View File

@@ -30,17 +30,9 @@ pub enum Error {
Flume(#[from] flume::RecvError),
#[error(transparent)]
#[cfg(not(target_arch = "wasm32"))]
Ureq(#[from] Box<ureq::Error>),
Reqwest(#[from] reqwest::Error),
#[error(transparent)]
#[cfg(not(target_arch = "wasm32"))]
Session(#[from] pubky_common::session::Error),
}
#[cfg(not(target_arch = "wasm32"))]
impl From<ureq::Error> for Error {
fn from(error: ureq::Error) -> Self {
Error::Ureq(Box::new(error))
}
}

View File

@@ -16,7 +16,6 @@ macro_rules! if_wasm {
if_not_wasm! {
mod client;
mod client_async;
use client::PubkyClient;
}

View File

@@ -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(),
}
}

View File

@@ -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<String, JsValue> {
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<Vec<u8>>,
) -> Result<web_sys::Response, JsValue> {
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);