@@ -24,6 +24,7 @@ const UPLOADED: &str = "uploaded";
2424const LEFT : & str = "left" ;
2525const EVENT : & str = "event" ;
2626const COMPACT : & str = "compact" ;
27+ const NUMWANT : & str = "numwant" ;
2728
2829/// The `Announce` request. Fields use the domain types after parsing the
2930/// query params of the request.
@@ -43,7 +44,8 @@ const COMPACT: &str = "compact";
4344/// uploaded: Some(NumberOfBytes::new(1)),
4445/// left: Some(NumberOfBytes::new(1)),
4546/// event: Some(Event::Started),
46- /// compact: Some(Compact::NotAccepted)
47+ /// compact: Some(Compact::NotAccepted),
48+ /// numwant: Some(50)
4749/// };
4850/// ```
4951///
@@ -59,8 +61,10 @@ pub struct Announce {
5961 // Mandatory params
6062 /// The `InfoHash` of the torrent.
6163 pub info_hash : InfoHash ,
64+
6265 /// The `PeerId` of the peer.
6366 pub peer_id : PeerId ,
67+
6468 /// The port of the peer.
6569 pub port : u16 ,
6670
@@ -80,6 +84,10 @@ pub struct Announce {
8084
8185 /// Whether the response should be in compact mode or not.
8286 pub compact : Option < Compact > ,
87+
88+ /// Number of peers that the client would receive from the tracker. The
89+ /// value is permitted to be zero.
90+ pub numwant : Option < u32 > ,
8391}
8492
8593/// Errors that can occur when parsing the `Announce` request.
@@ -244,6 +252,7 @@ impl TryFrom<Query> for Announce {
244252 left : extract_left ( & query) ?,
245253 event : extract_event ( & query) ?,
246254 compact : extract_compact ( & query) ?,
255+ numwant : extract_numwant ( & query) ?,
247256 } )
248257 }
249258}
@@ -350,6 +359,22 @@ fn extract_compact(query: &Query) -> Result<Option<Compact>, ParseAnnounceQueryE
350359 }
351360}
352361
362+ fn extract_numwant ( query : & Query ) -> Result < Option < u32 > , ParseAnnounceQueryError > {
363+ print ! ( "numwant {query:#?}" ) ;
364+
365+ match query. get_param ( NUMWANT ) {
366+ Some ( raw_param) => match u32:: from_str ( & raw_param) {
367+ Ok ( numwant) => Ok ( Some ( numwant) ) ,
368+ Err ( _) => Err ( ParseAnnounceQueryError :: InvalidParam {
369+ param_name : NUMWANT . to_owned ( ) ,
370+ param_value : raw_param. clone ( ) ,
371+ location : Location :: caller ( ) ,
372+ } ) ,
373+ } ,
374+ None => Ok ( None ) ,
375+ }
376+ }
377+
353378#[ cfg( test) ]
354379mod tests {
355380
@@ -360,7 +385,7 @@ mod tests {
360385
361386 use crate :: servers:: http:: v1:: query:: Query ;
362387 use crate :: servers:: http:: v1:: requests:: announce:: {
363- Announce , Compact , Event , COMPACT , DOWNLOADED , EVENT , INFO_HASH , LEFT , PEER_ID , PORT , UPLOADED ,
388+ Announce , Compact , Event , COMPACT , DOWNLOADED , EVENT , INFO_HASH , LEFT , NUMWANT , PEER_ID , PORT , UPLOADED ,
364389 } ;
365390
366391 #[ test]
@@ -387,6 +412,7 @@ mod tests {
387412 left: None ,
388413 event: None ,
389414 compact: None ,
415+ numwant: None ,
390416 }
391417 ) ;
392418 }
@@ -402,6 +428,7 @@ mod tests {
402428 ( LEFT , "3" ) ,
403429 ( EVENT , "started" ) ,
404430 ( COMPACT , "0" ) ,
431+ ( NUMWANT , "50" ) ,
405432 ] )
406433 . to_string ( ) ;
407434
@@ -420,6 +447,7 @@ mod tests {
420447 left: Some ( NumberOfBytes :: new( 3 ) ) ,
421448 event: Some ( Event :: Started ) ,
422449 compact: Some ( Compact :: NotAccepted ) ,
450+ numwant: Some ( 50 ) ,
423451 }
424452 ) ;
425453 }
@@ -428,7 +456,7 @@ mod tests {
428456
429457 use crate :: servers:: http:: v1:: query:: Query ;
430458 use crate :: servers:: http:: v1:: requests:: announce:: {
431- Announce , COMPACT , DOWNLOADED , EVENT , INFO_HASH , LEFT , PEER_ID , PORT , UPLOADED ,
459+ Announce , COMPACT , DOWNLOADED , EVENT , INFO_HASH , LEFT , NUMWANT , PEER_ID , PORT , UPLOADED ,
432460 } ;
433461
434462 #[ test]
@@ -547,6 +575,19 @@ mod tests {
547575
548576 assert ! ( Announce :: try_from( raw_query. parse:: <Query >( ) . unwrap( ) ) . is_err( ) ) ;
549577 }
578+
579+ #[ test]
580+ fn it_should_fail_if_the_numwant_param_is_invalid ( ) {
581+ let raw_query = Query :: from ( vec ! [
582+ ( INFO_HASH , "%3B%24U%04%CF%5F%11%BB%DB%E1%20%1C%EAjk%F4Z%EE%1B%C0" ) ,
583+ ( PEER_ID , "-qB00000000000000001" ) ,
584+ ( PORT , "17548" ) ,
585+ ( NUMWANT , "-1" ) ,
586+ ] )
587+ . to_string ( ) ;
588+
589+ assert ! ( Announce :: try_from( raw_query. parse:: <Query >( ) . unwrap( ) ) . is_err( ) ) ;
590+ }
550591 }
551592 }
552593}
0 commit comments