|
1 | 1 | use super::{PeerAddr, TrackerTrait}; |
2 | | -use crate::errors::{HttpTrackerError, TrackerError}; |
| 2 | +use crate::{ |
| 3 | + errors::{HttpTrackerError, TrackerError}, |
| 4 | + hashes::InfoHash, |
| 5 | +}; |
3 | 6 | use rand::distr::{Alphanumeric, SampleString}; |
4 | 7 | use serde::{ |
5 | 8 | Deserialize, Serialize, |
@@ -55,13 +58,13 @@ impl TrackerRequest { |
55 | 58 | pub struct HttpTracker { |
56 | 59 | uri: String, |
57 | 60 | peer_id: String, |
58 | | - info_hash: String, |
| 61 | + info_hash: InfoHash, |
59 | 62 | params: TrackerRequest, |
60 | 63 | } |
61 | 64 |
|
62 | 65 | impl HttpTracker { |
63 | 66 | #[instrument(skip(info_hash), fields(uri = %uri))] |
64 | | - pub fn new(uri: String, info_hash: String) -> HttpTracker { |
| 67 | + pub fn new(uri: String, info_hash: InfoHash) -> HttpTracker { |
65 | 68 | let peer_id = Alphanumeric.sample_string(&mut rand::rng(), 20); |
66 | 69 | debug!(peer_id = %peer_id, "Generated peer ID"); |
67 | 70 |
|
@@ -93,27 +96,14 @@ impl TrackerTrait for HttpTracker { |
93 | 96 | async fn stream_peers(&mut self) -> anyhow::Result<Vec<PeerAddr>> { |
94 | 97 | // Decode info_hash |
95 | 98 | debug!("Decoding info hash"); |
96 | | - let info_hash_part = self.info_hash.split("urn:btih:").last().ok_or_else(|| { |
97 | | - HttpTrackerError::InvalidInfoHash(format!("Invalid info_hash format: {}", self.info_hash)) |
98 | | - })?; |
99 | | - |
100 | | - let decoded_hash = hex::decode(info_hash_part).map_err(|e| { |
101 | | - error!(error = %e, "Failed to decode info_hash"); |
102 | | - HttpTrackerError::InvalidInfoHash(format!("Failed to decode info_hash: {}", e)) |
103 | | - })?; |
104 | | - |
105 | | - let info_hash: [u8; 20] = decoded_hash.try_into().map_err(|_| { |
106 | | - error!("Info hash has incorrect length"); |
107 | | - HttpTrackerError::InvalidInfoHash("Info hash must be 20 bytes".to_string()) |
108 | | - })?; |
109 | 99 |
|
110 | 100 | // Generate params + URL. Specifically using the compact format by adding "compact=1" to |
111 | 101 | // params. |
112 | 102 | debug!("Generating request parameters"); |
113 | 103 | let params = serde_qs::to_string(&self.params) |
114 | 104 | .map_err(|e| HttpTrackerError::ParameterEncoding(e.to_string()))?; |
115 | 105 |
|
116 | | - let info_hash_encoded = urlencode(&info_hash); |
| 106 | + let info_hash_encoded = urlencode(self.info_hash.as_bytes()); |
117 | 107 | trace!(encoded_hash = %info_hash_encoded, "URL-encoded info hash"); |
118 | 108 |
|
119 | 109 | let uri_params = format!( |
@@ -238,10 +228,10 @@ mod tests { |
238 | 228 | let metainfo = MagnetUri::parse(contents).await.unwrap(); |
239 | 229 | match metainfo { |
240 | 230 | MetaInfo::MagnetUri(magnet) => { |
| 231 | + let info_hash = magnet.info_hash(); |
241 | 232 | let announce_list = magnet.announce_list.unwrap(); |
242 | 233 | let announce_uri = announce_list[0].uri(); |
243 | | - let info_hash = magnet.info_hash; |
244 | | - let mut http_tracker = HttpTracker::new(announce_uri, info_hash); |
| 234 | + let mut http_tracker = HttpTracker::new(announce_uri, info_hash.unwrap()); |
245 | 235 |
|
246 | 236 | // Make request |
247 | 237 | let res = HttpTracker::stream_peers(&mut http_tracker) |
|
0 commit comments