1- use crate :: common:: * ;
1+ use { crate :: common:: * , url :: form_urlencoded :: byte_serialize as urlencode } ;
22
33#[ derive( Clone , Debug , PartialEq ) ]
44pub ( crate ) struct MagnetLink {
@@ -62,7 +62,9 @@ impl MagnetLink {
6262
6363 for tracker in & self . trackers {
6464 query. push_str ( "&tr=" ) ;
65- query. push_str ( tracker. as_str ( ) ) ;
65+ for part in urlencode ( tracker. as_str ( ) . as_bytes ( ) ) {
66+ query. push_str ( part) ;
67+ }
6668 }
6769
6870 for peer in & self . peers {
@@ -210,7 +212,7 @@ mod tests {
210212 link. add_tracker ( Url :: parse ( "http://foo.com/announce" ) . unwrap ( ) ) ;
211213 assert_eq ! (
212214 link. to_url( ) . as_str( ) ,
213- "magnet:?xt=urn:btih:da39a3ee5e6b4b0d3255bfef95601890afd80709&tr=http://foo .com/announce "
215+ "magnet:?xt=urn:btih:da39a3ee5e6b4b0d3255bfef95601890afd80709&tr=http%3A%2F%2Ffoo .com%2Fannounce "
214216 ) ;
215217 }
216218
@@ -240,8 +242,8 @@ mod tests {
240242 concat!(
241243 "magnet:?xt=urn:btih:da39a3ee5e6b4b0d3255bfef95601890afd80709" ,
242244 "&dn=foo" ,
243- "&tr=http://foo .com/announce " ,
244- "&tr=http://bar .net/announce " ,
245+ "&tr=http%3A%2F%2Ffoo .com%2Fannounce " ,
246+ "&tr=http%3A%2F%2Fbar .net%2Fannounce " ,
245247 "&x.pe=foo.com:1337" ,
246248 "&x.pe=bar.net:666" ,
247249 ) ,
@@ -263,6 +265,37 @@ mod tests {
263265 assert_eq ! ( link_to, link_from) ;
264266 }
265267
268+ #[ test]
269+ fn link_from_str_tracker_round_trip ( ) {
270+ let magnet_str = concat ! (
271+ "magnet:?xt=urn:btih:da39a3ee5e6b4b0d3255bfef95601890afd80709" ,
272+ "&dn=foo" ,
273+ "&tr=http%3A%2F%2Ffoo.com%2Fannounce" ,
274+ "&tr=http%3A%2F%2Fbar.net%2Fannounce"
275+ ) ;
276+
277+ let link_from = MagnetLink :: from_str ( magnet_str) . unwrap ( ) ;
278+ let link_roundtripped = MagnetLink :: from_str ( & link_from. to_string ( ) ) . unwrap ( ) ;
279+ assert_eq ! ( link_from, link_roundtripped, ) ;
280+ }
281+
282+ #[ test]
283+ fn link_from_str_tracker_urlencoding ( ) {
284+ let magnet_str = concat ! (
285+ "magnet:?xt=urn:btih:da39a3ee5e6b4b0d3255bfef95601890afd80709" ,
286+ "&dn=foo" ,
287+ "&tr=http%3A%2F%2Ffoo.com%2Fannounce" ,
288+ ) ;
289+
290+ let link_from = MagnetLink :: from_str ( magnet_str) . unwrap ( ) ;
291+ let tracker_url = link_from. trackers . first ( ) . unwrap ( ) ;
292+
293+ assert_eq ! (
294+ tracker_url,
295+ & "http://foo.com/announce" . parse:: <Url >( ) . unwrap( ) ,
296+ ) ;
297+ }
298+
266299 #[ test]
267300 fn link_from_str_url_error ( ) {
268301 let link = "%imdl.io" ;
0 commit comments