diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2026-01-08 12:02:59 +0000 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2026-01-08 12:14:27 +0000 |
| commit | 0356740d11c9fb6524060e6755ab0c2186096724 (patch) | |
| tree | db7ca39d1cb6b078d40fde14d3a84cfbf443eaab /src/sync | |
| parent | 64eaf4407028d3727fe8854a9a8fb97a8660af95 (diff) | |
fix: sync-bootstrap-relay-url scheme optional
Diffstat (limited to 'src/sync')
| -rw-r--r-- | src/sync/relay_connection.rs | 101 |
1 files changed, 97 insertions, 4 deletions
diff --git a/src/sync/relay_connection.rs b/src/sync/relay_connection.rs index bd9ab80..21d864d 100644 --- a/src/sync/relay_connection.rs +++ b/src/sync/relay_connection.rs | |||
| @@ -79,14 +79,38 @@ pub struct RelayConnection { | |||
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | impl RelayConnection { | 81 | impl RelayConnection { |
| 82 | /// Normalize a relay URL to include a scheme (wss:// or ws://) | ||
| 83 | /// | ||
| 84 | /// If the URL already has a scheme, it's returned as-is. | ||
| 85 | /// If no scheme is provided, wss:// is assumed (secure by default). | ||
| 86 | /// | ||
| 87 | /// # Arguments | ||
| 88 | /// * `url` - The relay URL (with or without scheme) | ||
| 89 | /// | ||
| 90 | /// # Returns | ||
| 91 | /// The normalized URL with scheme | ||
| 92 | /// | ||
| 93 | /// # Examples | ||
| 94 | /// - `"relay.example.com"` -> `"wss://relay.example.com"` | ||
| 95 | /// - `"wss://relay.example.com"` -> `"wss://relay.example.com"` | ||
| 96 | /// - `"ws://relay.example.com"` -> `"ws://relay.example.com"` | ||
| 97 | fn normalize_url(url: &str) -> String { | ||
| 98 | if url.starts_with("wss://") || url.starts_with("ws://") { | ||
| 99 | url.to_string() | ||
| 100 | } else { | ||
| 101 | format!("wss://{}", url) | ||
| 102 | } | ||
| 103 | } | ||
| 104 | |||
| 82 | /// Create a new relay connection (not yet connected) | 105 | /// Create a new relay connection (not yet connected) |
| 83 | /// | 106 | /// |
| 84 | /// # Arguments | 107 | /// # Arguments |
| 85 | /// * `url` - The relay URL to connect to (e.g., "wss://relay.example.com") | 108 | /// * `url` - The relay URL to connect to (with or without scheme, e.g., "relay.example.com" or "wss://relay.example.com") |
| 86 | pub fn new(url: String) -> Self { | 109 | pub fn new(url: String) -> Self { |
| 110 | let normalized_url = Self::normalize_url(&url); | ||
| 87 | let client = Client::default(); | 111 | let client = Client::default(); |
| 88 | Self { | 112 | Self { |
| 89 | url, | 113 | url: normalized_url, |
| 90 | client, | 114 | client, |
| 91 | database: None, | 115 | database: None, |
| 92 | nip77_warning_logged: std::sync::Arc::new(std::sync::atomic::AtomicBool::new(false)), | 116 | nip77_warning_logged: std::sync::Arc::new(std::sync::atomic::AtomicBool::new(false)), |
| @@ -96,12 +120,13 @@ impl RelayConnection { | |||
| 96 | /// Create a new relay connection with database for negentropy sync | 120 | /// Create a new relay connection with database for negentropy sync |
| 97 | /// | 121 | /// |
| 98 | /// # Arguments | 122 | /// # Arguments |
| 99 | /// * `url` - The relay URL to connect to (e.g., "wss://relay.example.com") | 123 | /// * `url` - The relay URL to connect to (with or without scheme, e.g., "relay.example.com" or "wss://relay.example.com") |
| 100 | /// * `database` - Shared database for local event comparison during negentropy sync | 124 | /// * `database` - Shared database for local event comparison during negentropy sync |
| 101 | pub fn new_with_database(url: String, database: SharedDatabase) -> Self { | 125 | pub fn new_with_database(url: String, database: SharedDatabase) -> Self { |
| 126 | let normalized_url = Self::normalize_url(&url); | ||
| 102 | let client = Client::default(); | 127 | let client = Client::default(); |
| 103 | Self { | 128 | Self { |
| 104 | url, | 129 | url: normalized_url, |
| 105 | client, | 130 | client, |
| 106 | database: Some(database), | 131 | database: Some(database), |
| 107 | nip77_warning_logged: std::sync::Arc::new(std::sync::atomic::AtomicBool::new(false)), | 132 | nip77_warning_logged: std::sync::Arc::new(std::sync::atomic::AtomicBool::new(false)), |
| @@ -491,3 +516,71 @@ impl RelayConnection { | |||
| 491 | self.database.is_some() | 516 | self.database.is_some() |
| 492 | } | 517 | } |
| 493 | } | 518 | } |
| 519 | |||
| 520 | #[cfg(test)] | ||
| 521 | mod tests { | ||
| 522 | use super::*; | ||
| 523 | |||
| 524 | #[test] | ||
| 525 | fn test_normalize_url_with_wss_scheme() { | ||
| 526 | let url = "wss://relay.example.com"; | ||
| 527 | assert_eq!(RelayConnection::normalize_url(url), "wss://relay.example.com"); | ||
| 528 | } | ||
| 529 | |||
| 530 | #[test] | ||
| 531 | fn test_normalize_url_with_ws_scheme() { | ||
| 532 | let url = "ws://relay.example.com"; | ||
| 533 | assert_eq!(RelayConnection::normalize_url(url), "ws://relay.example.com"); | ||
| 534 | } | ||
| 535 | |||
| 536 | #[test] | ||
| 537 | fn test_normalize_url_without_scheme() { | ||
| 538 | let url = "relay.example.com"; | ||
| 539 | assert_eq!(RelayConnection::normalize_url(url), "wss://relay.example.com"); | ||
| 540 | } | ||
| 541 | |||
| 542 | #[test] | ||
| 543 | fn test_normalize_url_without_scheme_with_port() { | ||
| 544 | let url = "relay.example.com:8080"; | ||
| 545 | assert_eq!(RelayConnection::normalize_url(url), "wss://relay.example.com:8080"); | ||
| 546 | } | ||
| 547 | |||
| 548 | #[test] | ||
| 549 | fn test_normalize_url_with_path() { | ||
| 550 | let url = "relay.example.com/nostr"; | ||
| 551 | assert_eq!(RelayConnection::normalize_url(url), "wss://relay.example.com/nostr"); | ||
| 552 | } | ||
| 553 | |||
| 554 | #[test] | ||
| 555 | fn test_new_normalizes_url() { | ||
| 556 | let conn = RelayConnection::new("relay.example.com".to_string()); | ||
| 557 | assert_eq!(conn.url(), "wss://relay.example.com"); | ||
| 558 | } | ||
| 559 | |||
| 560 | #[test] | ||
| 561 | fn test_new_preserves_wss_scheme() { | ||
| 562 | let conn = RelayConnection::new("wss://relay.example.com".to_string()); | ||
| 563 | assert_eq!(conn.url(), "wss://relay.example.com"); | ||
| 564 | } | ||
| 565 | |||
| 566 | #[test] | ||
| 567 | fn test_new_preserves_ws_scheme() { | ||
| 568 | let conn = RelayConnection::new("ws://relay.example.com".to_string()); | ||
| 569 | assert_eq!(conn.url(), "ws://relay.example.com"); | ||
| 570 | } | ||
| 571 | |||
| 572 | #[test] | ||
| 573 | fn test_new_with_database_normalizes_url() { | ||
| 574 | // This test just verifies the URL normalization works | ||
| 575 | // We can't easily test with_database without a real database | ||
| 576 | let conn = RelayConnection::new("git.shakespeare.diy".to_string()); | ||
| 577 | assert_eq!(conn.url(), "wss://git.shakespeare.diy"); | ||
| 578 | } | ||
| 579 | |||
| 580 | #[test] | ||
| 581 | fn test_normalize_url_real_world_example() { | ||
| 582 | // Test the exact case from the bug report | ||
| 583 | let url = "git.shakespeare.diy"; | ||
| 584 | assert_eq!(RelayConnection::normalize_url(url), "wss://git.shakespeare.diy"); | ||
| 585 | } | ||
| 586 | } | ||