Skip to content

Commit c10b379

Browse files
committed
fex: [#811] missing tracker key in torrent
when the tracker URL doesn't have a trailing slash. For example, this tracker URL in the configuration: https://127.0.0.1:7070/announce produces this tracker URL in the torrent: https://127.0.0.1:7070/mCGfCr8nvixxA0h8B4iz0sT8V3FIQLi7 and it should produce: https://127.0.0.1:7070/announce/mCGfCr8nvixxA0h8B4iz0sT8V3FIQLi7
1 parent 2a45dcc commit c10b379

File tree

1 file changed

+79
-3
lines changed

1 file changed

+79
-3
lines changed

src/tracker/service.rs

Lines changed: 79 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -376,9 +376,7 @@ impl Service {
376376
/// It builds the announce url appending the user tracker key.
377377
/// Eg: <https://tracker:7070/USER_TRACKER_KEY>
378378
fn announce_url_with_key(&self, tracker_key: &TrackerKey) -> Url {
379-
self.tracker_url
380-
.join(&tracker_key.key)
381-
.expect("a tracker key should be added to the tracker base URL")
379+
build_announce_url_with_key(&self.tracker_url, &tracker_key.key)
382380
}
383381

384382
fn invalid_token_body() -> String {
@@ -390,8 +388,86 @@ impl Service {
390388
}
391389
}
392390

391+
/// Builds the announce URL by properly appending the tracker key to the base URL.
392+
///
393+
/// This function handles the case where the base URL ends with a path segment (like "/announce")
394+
/// and ensures the tracker key is appended as a new path segment rather than replacing the last one.
395+
///
396+
/// # Arguments
397+
/// * `base_url` - The base tracker URL (e.g., "https://127.0.0.1:7070/announce")
398+
/// * `tracker_key` - The user's tracker key to append
399+
///
400+
/// # Returns
401+
/// A URL with the tracker key properly appended (e.g., "https://127.0.0.1:7070/announce/mCGfCr8nvixxA0h8B4iz0sT8V3FIQLi7")
402+
fn build_announce_url_with_key(base_url: &Url, tracker_key: &str) -> Url {
403+
let mut url = base_url.clone();
404+
405+
// Ensure the path ends with a trailing slash so join() appends rather than replaces
406+
if !url.path().ends_with('/') {
407+
url.set_path(&format!("{}/", url.path()));
408+
}
409+
410+
url.join(tracker_key)
411+
.expect("tracker key should be a valid URL segment")
412+
}
413+
393414
/// Temporary patch to map `StatusCode` from crate `http` 0.2.11 to `http` v1.0.0
394415
/// until `reqwest` upgrades to hyper 1.0. See <https://github.com/seanmonstar/reqwest/issues/2039>
395416
fn map_status_code(status: reqwest::StatusCode) -> hyper::StatusCode {
396417
StatusCode::from_u16(status.as_u16()).unwrap()
397418
}
419+
420+
#[cfg(test)]
421+
mod tests {
422+
use super::*;
423+
424+
#[test]
425+
fn test_build_announce_url_with_key_with_announce_path() {
426+
let base_url = Url::parse("https://127.0.0.1:7070/announce").unwrap();
427+
let tracker_key = "mCGfCr8nvixxA0h8B4iz0sT8V3FIQLi7";
428+
429+
let result = build_announce_url_with_key(&base_url, tracker_key);
430+
431+
assert_eq!(result.to_string(), "https://127.0.0.1:7070/announce/mCGfCr8nvixxA0h8B4iz0sT8V3FIQLi7");
432+
}
433+
434+
#[test]
435+
fn test_build_announce_url_with_key_with_trailing_slash() {
436+
let base_url = Url::parse("https://127.0.0.1:7070/announce/").unwrap();
437+
let tracker_key = "mCGfCr8nvixxA0h8B4iz0sT8V3FIQLi7";
438+
439+
let result = build_announce_url_with_key(&base_url, tracker_key);
440+
441+
assert_eq!(result.to_string(), "https://127.0.0.1:7070/announce/mCGfCr8nvixxA0h8B4iz0sT8V3FIQLi7");
442+
}
443+
444+
#[test]
445+
fn test_build_announce_url_with_key_root_path() {
446+
let base_url = Url::parse("https://tracker.example.com/").unwrap();
447+
let tracker_key = "testkey123";
448+
449+
let result = build_announce_url_with_key(&base_url, tracker_key);
450+
451+
assert_eq!(result.to_string(), "https://tracker.example.com/testkey123");
452+
}
453+
454+
#[test]
455+
fn test_build_announce_url_with_key_no_path() {
456+
let base_url = Url::parse("https://tracker.example.com").unwrap();
457+
let tracker_key = "testkey123";
458+
459+
let result = build_announce_url_with_key(&base_url, tracker_key);
460+
461+
assert_eq!(result.to_string(), "https://tracker.example.com/testkey123");
462+
}
463+
464+
#[test]
465+
fn test_build_announce_url_with_key_multiple_path_segments() {
466+
let base_url = Url::parse("https://tracker.example.com/api/v1/announce").unwrap();
467+
let tracker_key = "complexkey456";
468+
469+
let result = build_announce_url_with_key(&base_url, tracker_key);
470+
471+
assert_eq!(result.to_string(), "https://tracker.example.com/api/v1/announce/complexkey456");
472+
}
473+
}

0 commit comments

Comments
 (0)