I’m doing the Bittorrent challenge in Rust. In stage #JV8, I’ve found that the tracker’s response contains invalid Bencoded data about half the time. I received a response from the tracker containing these bytes:
b"d12:min intervali60e5:peers18:\xa5\xe8#r\xc8\xda\xa5\xe8&\xa4\xc8\xef\xa5\xe8)I\xc9)8:completei3e10:incompletei2e8:intervali60ee"
This is invalid because Bencode requires dictionary keys to be sorted (the spec says “Keys must be strings and appear in sorted order”), and the keys in this response are not sorted. My Bencode parser therefore rejects the tracker’s response.
Here’s a snippet of my code:
let url_encoded_info_hash = urlencoding::encode_binary(metainfo.info.hash()?.as_ref());
let url_encoded_peer_id = urlencoding::encode_binary(our_peer_id.as_ref().as_slice());
let base_url = format!(
"{}?info_hash={}&peer_id={}",
metainfo.announce.as_str(),
&url_encoded_info_hash,
&url_encoded_peer_id,
);
let length_str = metainfo.info.length.to_string();
let other_query_params = [
("port", "6881"),
("uploaded", "0"),
("downloaded", "0"),
("left", length_str.as_str()),
("compact", "1"),
];
let url = Url::parse_with_params(base_url.as_str(), &other_query_params)?;
eprintln!("Sending HTTP request to tracker");
let response = http_client
.get(url)
.header(ACCEPT, MIME_TYPE_BITTORRENT)
.send()
.await?;
let body = response.bytes().await?;
eprintln!("Got response:");
eprintln!("{body:?}");