max / makenotwork
1 file changed,
+24 insertions,
-2 deletions
| @@ -36,6 +36,20 @@ async fn read_capped_json<T: serde::de::DeserializeOwned>( | |||
| 36 | 36 | serde_json::from_slice(&bytes).ok() | |
| 37 | 37 | } | |
| 38 | 38 | ||
| 39 | + | /// Build the base URL for a peer's API from its configured address. | |
| 40 | + | /// | |
| 41 | + | /// Honors a scheme already present in the address (so an operator can set | |
| 42 | + | /// `https://host:port` when the hop crosses an untrusted network), and otherwise | |
| 43 | + | /// defaults to `http://` — the tailnet deployment where WireGuard already | |
| 44 | + | /// encrypts the transport, and pom's own API server binds plain HTTP. | |
| 45 | + | fn peer_base_url(address: &str) -> String { | |
| 46 | + | if address.contains("://") { | |
| 47 | + | address.trim_end_matches('/').to_string() | |
| 48 | + | } else { | |
| 49 | + | format!("http://{address}") | |
| 50 | + | } | |
| 51 | + | } | |
| 52 | + | ||
| 39 | 53 | // --- Identity --- | |
| 40 | 54 | ||
| 41 | 55 | /// Load or create a persistent instance ID (UUID v4). | |
| @@ -216,6 +230,7 @@ async fn heartbeat_loop( | |||
| 216 | 230 | None => return, | |
| 217 | 231 | } | |
| 218 | 232 | }; | |
| 233 | + | let base = peer_base_url(&address); | |
| 219 | 234 | ||
| 220 | 235 | let client = reqwest::Client::builder() | |
| 221 | 236 | .timeout(std::time::Duration::from_secs(10)) | |
| @@ -229,7 +244,7 @@ async fn heartbeat_loop( | |||
| 229 | 244 | } | |
| 230 | 245 | ||
| 231 | 246 | let start = std::time::Instant::now(); | |
| 232 | - | let mut req = client.get(format!("http://{address}/api/peer/info")); | |
| 247 | + | let mut req = client.get(format!("{base}/api/peer/info")); | |
| 233 | 248 | if let Some(ref t) = auth_token { | |
| 234 | 249 | req = req.bearer_auth(t); | |
| 235 | 250 | } | |
| @@ -247,7 +262,7 @@ async fn heartbeat_loop( | |||
| 247 | 262 | } | |
| 248 | 263 | ||
| 249 | 264 | // Also fetch /api/peer/status for mesh aggregation | |
| 250 | - | let mut status_req = client.get(format!("http://{address}/api/peer/status")); | |
| 265 | + | let mut status_req = client.get(format!("{base}/api/peer/status")); | |
| 251 | 266 | if let Some(ref t) = auth_token { | |
| 252 | 267 | status_req = status_req.bearer_auth(t); | |
| 253 | 268 | } | |
| @@ -416,6 +431,13 @@ mod tests { | |||
| 416 | 431 | use super::*; | |
| 417 | 432 | ||
| 418 | 433 | #[test] | |
| 434 | + | fn peer_base_url_honors_scheme() { | |
| 435 | + | assert_eq!(peer_base_url("host:9100"), "http://host:9100"); | |
| 436 | + | assert_eq!(peer_base_url("https://host:9100"), "https://host:9100"); | |
| 437 | + | assert_eq!(peer_base_url("https://host:9100/"), "https://host:9100"); | |
| 438 | + | } | |
| 439 | + | ||
| 440 | + | #[test] | |
| 419 | 441 | fn override_id_takes_precedence() { | |
| 420 | 442 | let id = load_or_create_instance_id(Some("override-id")).unwrap(); | |
| 421 | 443 | assert_eq!(id, "override-id"); |