Skip to content

Commit

Permalink
nostr: add trailing slash handling to RelayUrl
Browse files Browse the repository at this point in the history
Signed-off-by: Yuki Kishimoto <[email protected]>
  • Loading branch information
yukibtc committed Nov 26, 2024
1 parent fd9326c commit 734d25d
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 27 deletions.
36 changes: 18 additions & 18 deletions crates/nostr/src/event/tag/standard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1348,7 +1348,7 @@ mod tests {
vec![
"q",
"378f145897eea948952674269945e88612420db35791784abf0616b4fed56ef7",
"wss://relay.damus.io/"
"wss://relay.damus.io"
],
TagStandard::Quote {
event_id: EventId::from_hex(
Expand Down Expand Up @@ -1411,7 +1411,7 @@ mod tests {
vec![
"p",
"13adc511de7e1cfcf1c6b7f6365fb5a03442d7bcacf565ea57fa7770912c023d",
"wss://relay.damus.io/"
"wss://relay.damus.io"
],
TagStandard::PublicKey {
public_key: PublicKey::from_str(
Expand Down Expand Up @@ -1447,7 +1447,7 @@ mod tests {
vec![
"e",
"378f145897eea948952674269945e88612420db35791784abf0616b4fed56ef7",
"wss://relay.damus.io/"
"wss://relay.damus.io"
],
TagStandard::Event {
event_id: EventId::from_hex(
Expand Down Expand Up @@ -1527,7 +1527,7 @@ mod tests {
vec![
"a",
"30023:a695f6b60119d9521934a691347d9f78e8770b56da16bb255ee286ddf9fda919:ipsum",
"wss://relay.nostr.org/"
"wss://relay.nostr.org"
],
TagStandard::Coordinate {
coordinate: Coordinate::new(
Expand All @@ -1548,7 +1548,7 @@ mod tests {
vec![
"p",
"13adc511de7e1cfcf1c6b7f6365fb5a03442d7bcacf565ea57fa7770912c023d",
"wss://relay.damus.io/",
"wss://relay.damus.io",
"Speaker",
],
TagStandard::PublicKeyLiveEvent {
Expand Down Expand Up @@ -1586,7 +1586,7 @@ mod tests {
vec![
"p",
"13adc511de7e1cfcf1c6b7f6365fb5a03442d7bcacf565ea57fa7770912c023d",
"wss://relay.damus.io/",
"wss://relay.damus.io",
"alias",
],
TagStandard::PublicKey {
Expand Down Expand Up @@ -1694,7 +1694,7 @@ mod tests {
vec![
"p",
"13adc511de7e1cfcf1c6b7f6365fb5a03442d7bcacf565ea57fa7770912c023d",
"wss://relay.damus.io/",
"wss://relay.damus.io",
"Host",
"a5d9290ef9659083c490b303eb7ee41356d8778ff19f2f91776c8dc4443388a64ffcf336e61af4c25c05ac3ae952d1ced889ed655b67790891222aaa15b99fdd"
],
Expand Down Expand Up @@ -1726,7 +1726,7 @@ mod tests {
assert_eq!(
vec!["r", "wss://atlas.nostr.land/"],
TagStandard::RelayMetadata {
relay_url: RelayUrl::parse("wss://atlas.nostr.land").unwrap(),
relay_url: RelayUrl::parse("wss://atlas.nostr.land/").unwrap(),
metadata: None
}
.to_vec()
Expand All @@ -1735,14 +1735,14 @@ mod tests {
assert_eq!(
vec!["r", "wss://atlas.nostr.land/", "read"],
TagStandard::RelayMetadata {
relay_url: RelayUrl::parse("wss://atlas.nostr.land").unwrap(),
relay_url: RelayUrl::parse("wss://atlas.nostr.land/").unwrap(),
metadata: Some(RelayMetadata::Read)
}
.to_vec()
);

assert_eq!(
vec!["r", "wss://atlas.nostr.land/", "write"],
vec!["r", "wss://atlas.nostr.land", "write"],
TagStandard::RelayMetadata {
relay_url: RelayUrl::parse("wss://atlas.nostr.land").unwrap(),
metadata: Some(RelayMetadata::Write)
Expand Down Expand Up @@ -1861,7 +1861,7 @@ mod tests {
TagStandard::parse(&[
"q",
"378f145897eea948952674269945e88612420db35791784abf0616b4fed56ef7",
"wss://relay.damus.io/"
"wss://relay.damus.io"
])
.unwrap(),
TagStandard::Quote {
Expand Down Expand Up @@ -1967,7 +1967,7 @@ mod tests {
TagStandard::parse(&[
"p",
"13adc511de7e1cfcf1c6b7f6365fb5a03442d7bcacf565ea57fa7770912c023d",
"wss://relay.damus.io/"
"wss://relay.damus.io"
])
.unwrap(),
TagStandard::PublicKey {
Expand Down Expand Up @@ -2004,7 +2004,7 @@ mod tests {
TagStandard::parse(&[
"e",
"378f145897eea948952674269945e88612420db35791784abf0616b4fed56ef7",
"wss://relay.damus.io/"
"wss://relay.damus.io"
])
.unwrap(),
TagStandard::Event {
Expand Down Expand Up @@ -2095,7 +2095,7 @@ mod tests {
TagStandard::parse(&[
"a",
"30023:a695f6b60119d9521934a691347d9f78e8770b56da16bb255ee286ddf9fda919:ipsum",
"wss://relay.nostr.org/"
"wss://relay.nostr.org"
])
.unwrap(),
TagStandard::Coordinate {
Expand All @@ -2115,21 +2115,21 @@ mod tests {
assert_eq!(
TagStandard::parse(&["r", "wss://atlas.nostr.land/"]).unwrap(),
TagStandard::RelayMetadata {
relay_url: RelayUrl::parse("wss://atlas.nostr.land").unwrap(),
relay_url: RelayUrl::parse("wss://atlas.nostr.land/").unwrap(),
metadata: None
}
);

assert_eq!(
TagStandard::parse(&["r", "wss://atlas.nostr.land/", "read"]).unwrap(),
TagStandard::parse(&["r", "wss://atlas.nostr.land", "read"]).unwrap(),
TagStandard::RelayMetadata {
relay_url: RelayUrl::parse("wss://atlas.nostr.land").unwrap(),
metadata: Some(RelayMetadata::Read)
}
);

assert_eq!(
TagStandard::parse(&["r", "wss://atlas.nostr.land/", "write"]).unwrap(),
TagStandard::parse(&["r", "wss://atlas.nostr.land", "write"]).unwrap(),
TagStandard::RelayMetadata {
relay_url: RelayUrl::parse("wss://atlas.nostr.land").unwrap(),
metadata: Some(RelayMetadata::Write)
Expand All @@ -2149,7 +2149,7 @@ mod tests {
"13adc511de7e1cfcf1c6b7f6365fb5a03442d7bcacf565ea57fa7770912c023d"
)
.unwrap(),
relay_url: Some(RelayUrl::parse("wss://relay.damus.io").unwrap()),
relay_url: Some(RelayUrl::parse("wss://relay.damus.io/").unwrap()),
alias: Some(String::from("alias")),
uppercase: false,
}
Expand Down
7 changes: 5 additions & 2 deletions crates/nostr/src/nips/nip19.rs
Original file line number Diff line number Diff line change
Expand Up @@ -822,8 +822,11 @@ mod tests {

assert_eq!(
Nip19::Profile(
Nip19Profile::new(expected_pubkey, ["wss://r.x.com", "wss://djbas.sadkb.com"])
.unwrap()
Nip19Profile::new(
expected_pubkey,
["wss://r.x.com/", "wss://djbas.sadkb.com/"]
)
.unwrap()
),
nip19
);
Expand Down
5 changes: 2 additions & 3 deletions crates/nostr/src/nips/nip47.rs
Original file line number Diff line number Diff line change
Expand Up @@ -977,8 +977,7 @@ impl FromStr for NostrWalletConnectURI {
impl fmt::Display for NostrWalletConnectURI {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// trailing slash is removed, this breaks some clients
let relay_url = self.relay_url.to_string();
let relay_url = relay_url.strip_suffix('/').unwrap_or(&relay_url);
let relay_url: &str = self.relay_url.as_str_without_trailing_slash();
write!(
f,
"{NOSTR_WALLET_CONNECT_URI_SCHEME}://{}?relay={}&secret={}",
Expand Down Expand Up @@ -1041,7 +1040,7 @@ mod tests {

#[test]
fn test_parse_uri() {
let uri = "nostr+walletconnect://b889ff5b1513b641e2a139f661a661364979c5beee91842f8f0ef42ab558e9d4?relay=wss%3A%2F%2Frelay.damus.io%2F&secret=71a8c14c1407c113601079c4302dab36460f0ccd0ad506f1f2dc73b5100e4f3c&lud16=nostr%40nostr.com";
let uri = "nostr+walletconnect://b889ff5b1513b641e2a139f661a661364979c5beee91842f8f0ef42ab558e9d4?relay=wss%3A%2F%2Frelay.damus.io&secret=71a8c14c1407c113601079c4302dab36460f0ccd0ad506f1f2dc73b5100e4f3c&lud16=nostr%40nostr.com";
let uri = NostrWalletConnectURI::from_str(uri).unwrap();

let pubkey =
Expand Down
37 changes: 33 additions & 4 deletions crates/nostr/src/types/url.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ impl From<ParseError> for Error {
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct RelayUrl {
url: Url,
has_trailing_slash: bool,
}

impl RelayUrl {
Expand All @@ -65,12 +66,18 @@ impl RelayUrl {
return Err(Error::MultipleSchemeSeparators);
}

// Check if has trailing slash
let has_trailing_slash: bool = url.ends_with('/');

// Parse URL
let url: Url = Url::parse(url)?;

// Check scheme
match url.scheme() {
"ws" | "wss" => Ok(Self { url }),
"ws" | "wss" => Ok(Self {
url,
has_trailing_slash,
}),
scheme => Err(Error::UnsupportedScheme(scheme.to_string())),
}
}
Expand All @@ -83,16 +90,29 @@ impl RelayUrl {
.map_or(false, |host| host.ends_with(".onion"))
}

/// Return the serialization of this relay URL without the trailing slash.
///
/// This method will always remove the trailing slash.
#[inline]
pub fn as_str_without_trailing_slash(&self) -> &str {
self.url.as_str().trim_end_matches('/')
}

/// Return the serialization of this relay URL.
///
/// The trailing slash will be removed only if the parsed URL hadn't it.
#[inline]
pub fn as_str(&self) -> &str {
if !self.has_trailing_slash {
return self.as_str_without_trailing_slash();
}

self.url.as_str()
}
}

impl fmt::Display for RelayUrl {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// TODO: if no path, remove last "/"
write!(f, "{}", self.as_str())
}
}
Expand Down Expand Up @@ -245,9 +265,18 @@ mod tests {
}

#[test]
fn test_relay_url_display() {
fn test_relay_url_as_str() {
let relay_url = RelayUrl::parse("ws://example.com").unwrap();
assert_eq!(relay_url.to_string(), "ws://example.com/");
assert_eq!(relay_url.as_str(), "ws://example.com");

let relay_url = RelayUrl::parse("ws://example.com/").unwrap();
assert_eq!(relay_url.as_str(), "ws://example.com/");

let relay_url = RelayUrl::parse("ws://example.com/").unwrap();
assert_eq!(
relay_url.as_str_without_trailing_slash(),
"ws://example.com"
);
}

#[test]
Expand Down

0 comments on commit 734d25d

Please sign in to comment.