Skip to content

Commit f4df806

Browse files
committed
feat: Add unknown_tracker_scheme crate feature
1 parent 69de021 commit f4df806

5 files changed

Lines changed: 57 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2020
- `TrackerScheme` no longer derives de/serialize because that's not actually
2121
used in torrent files
2222
- A torrent file with an invalid tracker URI (such as an unknown scheme) will now
23-
fail to parse as a `DecodedTorrent` and therefore as a `TorrentFile`
23+
fail to parse as a `DecodedTorrent` and therefore as a `TorrentFile`, unless the
24+
`unknown_tracker_scheme` variant is enabled, in which case it will produce a
25+
valid `TorrentFile` where the `TrackerScheme` is of the `Unknown` variant
2426

2527

2628
### Added
@@ -37,6 +39,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3739
a .torrent file
3840
- `DecodedTorrent::announce` and `DecodedTorrent::announce_list` list the
3941
trackers contained in the torrent file
42+
- `TrackerScheme::Unknown` stores unknown schemes instead of failing to parse,
43+
when the tracker URL scheme is not recognized, and when the `unknown_tracker_scheme`
44+
crate feature is anbled
4045

4146
### Fixed
4247

Cargo.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,16 @@ serde_json = "1"
3232

3333
[features]
3434
magnet_force_name = []
35+
unknown_tracker_scheme = []
3536

3637
[[test]]
3738
name = "magnet_force_name"
3839
path = "tests/magnet_force_name.rs"
3940
required-features = [ "magnet_force_name" ]
4041
test = true
42+
43+
[[test]]
44+
name = "unknown_tracker_scheme"
45+
path = "tests/unknown_tracker_scheme.rs"
46+
required-features = [ "unknown_tracker_scheme" ]
47+
test = true

src/torrent_file.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,7 @@ mod tests {
347347
}
348348

349349
#[test]
350+
#[cfg(not(feature = "unknown_tracker_scheme"))]
350351
fn fail_no_torrent_scheme() {
351352
let slice = std::fs::read("tests/libtorrent/good/sample.torrent").unwrap();
352353
let res = TorrentFile::from_slice(&slice);

src/tracker.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,15 @@ pub enum TrackerScheme {
8888
Websocket,
8989
Http,
9090
Udp,
91+
/// An unknown scheme is in the tracker URI.
92+
///
93+
/// This is also the case when there is no scheme, in which
94+
/// case the domain name may be parsed as a scheme.
95+
///
96+
/// This is disabled by default and required the `unknown_tracker_scheme`
97+
/// crate feature enabled if you really need to parse broken torrents.
98+
#[cfg(feature = "unknown_tracker_scheme")]
99+
Unknown(String),
91100
}
92101

93102
impl FromStr for TrackerScheme {
@@ -98,6 +107,9 @@ impl FromStr for TrackerScheme {
98107
"http" | "https" => Ok(Self::Http),
99108
"ws" => Ok(Self::Websocket),
100109
"udp" => Ok(Self::Udp),
110+
#[cfg(feature = "unknown_tracker_scheme")]
111+
_ => Ok(Self::Unknown(s.to_string())),
112+
#[cfg(not(feature = "unknown_tracker_scheme"))]
101113
_ => Err(TrackerError::InvalidScheme {
102114
scheme: s.to_string(),
103115
}),

tests/unknown_tracker_scheme.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
use hightorrent::{InfoHash, TorrentContent, TorrentFile};
2+
3+
use std::path::PathBuf;
4+
5+
#[test]
6+
fn can_parse_no_scheme_tracker() {
7+
// This only works when the unknown_tracker_scheme crate feature is eanbled
8+
let slice = std::fs::read("tests/libtorrent/good/sample.torrent").unwrap();
9+
let res = TorrentFile::from_slice(&slice);
10+
println!("{:?}", res);
11+
assert!(res.is_ok());
12+
let torrent = res.unwrap();
13+
assert_eq!(&torrent.name, "sample");
14+
assert_eq!(
15+
torrent.hash,
16+
InfoHash::V1("58d8d15a4eb3bd9afabc9cee2564f78192777edb".to_string())
17+
);
18+
assert_eq!(
19+
torrent.decoded.files().unwrap(),
20+
vec!(
21+
TorrentContent {
22+
path: PathBuf::from("text_file.txt"),
23+
size: 20,
24+
},
25+
TorrentContent {
26+
path: PathBuf::from("text_file2.txt"),
27+
size: 25,
28+
}
29+
),
30+
);
31+
}

0 commit comments

Comments
 (0)