use std::error;
use derive_more::{Display, Error};
use serde::{Deserialize, Serialize};
use serde_bencode::value::Value;
use serde_bencode::{de, Error};
use sha1::{Digest, Sha1};
use crate::models::info_hash::InfoHash;
use crate::models::torrent_file::Torrent;
#[derive(Debug, Display, PartialEq, Eq, Error)]
pub enum DecodeTorrentFileError {
#[display(fmt = "Torrent data could not be decoded from the bencoded format.")]
InvalidBencodeData,
#[display(fmt = "Torrent info dictionary key could not be decoded from the bencoded format.")]
InvalidInfoDictionary,
#[display(fmt = "Torrent has an invalid pieces key length. It should be a multiple of 20.")]
InvalidTorrentPiecesLength,
#[display(fmt = "Cannot bencode the parsed `info` dictionary again to generate the info-hash.")]
CannotBencodeInfoDict,
}
pub fn decode_and_validate_torrent_file(bytes: &[u8]) -> Result<(Torrent, InfoHash), DecodeTorrentFileError> {
let original_info_hash = calculate_info_hash(bytes)?;
let torrent = decode_torrent(bytes).map_err(|_| DecodeTorrentFileError::InvalidBencodeData)?;
if let Some(pieces) = torrent.info.pieces.as_ref() {
if pieces.as_ref().len() % 20 != 0 {
return Err(DecodeTorrentFileError::InvalidTorrentPiecesLength);
}
}
Ok((torrent, original_info_hash))
}
pub fn decode_torrent(bytes: &[u8]) -> Result<Torrent, Box<dyn error::Error>> {
match de::from_bytes::<Torrent>(bytes) {
Ok(torrent) => Ok(torrent),
Err(e) => {
println!("{e:?}");
Err(e.into())
}
}
}
pub fn encode_torrent(torrent: &Torrent) -> Result<Vec<u8>, Error> {
match serde_bencode::to_bytes(torrent) {
Ok(bencode_bytes) => Ok(bencode_bytes),
Err(e) => {
eprintln!("{e:?}");
Err(e)
}
}
}
#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct ParsedInfoDictFromMetainfoFile {
pub info: Value,
}
pub fn calculate_info_hash(bytes: &[u8]) -> Result<InfoHash, DecodeTorrentFileError> {
let metainfo: ParsedInfoDictFromMetainfoFile =
serde_bencode::from_bytes(bytes).map_err(|_| DecodeTorrentFileError::InvalidInfoDictionary)?;
let info_dict_bytes = serde_bencode::to_bytes(&metainfo.info).map_err(|_| DecodeTorrentFileError::CannotBencodeInfoDict)?;
let mut hasher = Sha1::new();
hasher.update(&info_dict_bytes);
let result = hasher.finalize();
Ok(InfoHash::from_bytes(&result))
}
#[cfg(test)]
mod tests {
use std::str::FromStr;
use crate::models::info_hash::InfoHash;
fn torrent_with_custom_info_dict_key() -> Vec<u8> {
[
100, 56, 58, 97, 110, 110, 111, 117, 110, 99, 101, 52, 49, 58, 104, 116, 116, 112, 115, 58, 47, 47, 97, 99, 97, 100,
101, 109, 105, 99, 116, 111, 114, 114, 101, 110, 116, 115, 46, 99, 111, 109, 47, 97, 110, 110, 111, 117, 110, 99,
101, 46, 112, 104, 112, 49, 51, 58, 97, 110, 110, 111, 117, 110, 99, 101, 45, 108, 105, 115, 116, 108, 108, 52, 49,
58, 104, 116, 116, 112, 115, 58, 47, 47, 97, 99, 97, 100, 101, 109, 105, 99, 116, 111, 114, 114, 101, 110, 116, 115,
46, 99, 111, 109, 47, 97, 110, 110, 111, 117, 110, 99, 101, 46, 112, 104, 112, 101, 108, 52, 54, 58, 104, 116, 116,
112, 115, 58, 47, 47, 105, 112, 118, 54, 46, 97, 99, 97, 100, 101, 109, 105, 99, 116, 111, 114, 114, 101, 110, 116,
115, 46, 99, 111, 109, 47, 97, 110, 110, 111, 117, 110, 99, 101, 46, 112, 104, 112, 101, 108, 52, 50, 58, 117, 100,
112, 58, 47, 47, 116, 114, 97, 99, 107, 101, 114, 46, 111, 112, 101, 110, 116, 114, 97, 99, 107, 114, 46, 111, 114,
103, 58, 49, 51, 51, 55, 47, 97, 110, 110, 111, 117, 110, 99, 101, 101, 108, 52, 52, 58, 117, 100, 112, 58, 47, 47,
116, 114, 97, 99, 107, 101, 114, 46, 111, 112, 101, 110, 98, 105, 116, 116, 111, 114, 114, 101, 110, 116, 46, 99,
111, 109, 58, 56, 48, 47, 97, 110, 110, 111, 117, 110, 99, 101, 101, 108, 51, 54, 58, 104, 116, 116, 112, 58, 47, 47,
98, 116, 49, 46, 97, 114, 99, 104, 105, 118, 101, 46, 111, 114, 103, 58, 54, 57, 54, 57, 47, 97, 110, 110, 111, 117,
110, 99, 101, 101, 108, 51, 54, 58, 104, 116, 116, 112, 58, 47, 47, 98, 116, 50, 46, 97, 114, 99, 104, 105, 118, 101,
46, 111, 114, 103, 58, 54, 57, 54, 57, 47, 97, 110, 110, 111, 117, 110, 99, 101, 101, 101, 55, 58, 99, 111, 109, 109,
101, 110, 116, 54, 51, 52, 58, 84, 104, 105, 115, 32, 99, 111, 110, 116, 101, 110, 116, 32, 104, 111, 115, 116, 101,
100, 32, 97, 116, 32, 116, 104, 101, 32, 73, 110, 116, 101, 114, 110, 101, 116, 32, 65, 114, 99, 104, 105, 118, 101,
32, 97, 116, 32, 104, 116, 116, 112, 115, 58, 47, 47, 97, 114, 99, 104, 105, 118, 101, 46, 111, 114, 103, 47, 100,
101, 116, 97, 105, 108, 115, 47, 114, 97, 112, 112, 112, 105, 100, 45, 119, 101, 105, 103, 104, 116, 115, 46, 116,
97, 114, 10, 70, 105, 108, 101, 115, 32, 109, 97, 121, 32, 104, 97, 118, 101, 32, 99, 104, 97, 110, 103, 101, 100,
44, 32, 119, 104, 105, 99, 104, 32, 112, 114, 101, 118, 101, 110, 116, 115, 32, 116, 111, 114, 114, 101, 110, 116,
115, 32, 102, 114, 111, 109, 32, 100, 111, 119, 110, 108, 111, 97, 100, 105, 110, 103, 32, 99, 111, 114, 114, 101,
99, 116, 108, 121, 32, 111, 114, 32, 99, 111, 109, 112, 108, 101, 116, 101, 108, 121, 59, 32, 112, 108, 101, 97, 115,
101, 32, 99, 104, 101, 99, 107, 32, 102, 111, 114, 32, 97, 110, 32, 117, 112, 100, 97, 116, 101, 100, 32, 116, 111,
114, 114, 101, 110, 116, 32, 97, 116, 32, 104, 116, 116, 112, 115, 58, 47, 47, 97, 114, 99, 104, 105, 118, 101, 46,
111, 114, 103, 47, 100, 111, 119, 110, 108, 111, 97, 100, 47, 114, 97, 112, 112, 112, 105, 100, 45, 119, 101, 105,
103, 104, 116, 115, 46, 116, 97, 114, 47, 114, 97, 112, 112, 112, 105, 100, 45, 119, 101, 105, 103, 104, 116, 115,
46, 116, 97, 114, 95, 97, 114, 99, 104, 105, 118, 101, 46, 116, 111, 114, 114, 101, 110, 116, 10, 78, 111, 116, 101,
58, 32, 114, 101, 116, 114, 105, 101, 118, 97, 108, 32, 117, 115, 117, 97, 108, 108, 121, 32, 114, 101, 113, 117,
105, 114, 101, 115, 32, 97, 32, 99, 108, 105, 101, 110, 116, 32, 116, 104, 97, 116, 32, 115, 117, 112, 112, 111, 114,
116, 115, 32, 119, 101, 98, 115, 101, 101, 100, 105, 110, 103, 32, 40, 71, 101, 116, 82, 105, 103, 104, 116, 32, 115,
116, 121, 108, 101, 41, 46, 10, 78, 111, 116, 101, 58, 32, 109, 97, 110, 121, 32, 73, 110, 116, 101, 114, 110, 101,
116, 32, 65, 114, 99, 104, 105, 118, 101, 32, 116, 111, 114, 114, 101, 110, 116, 115, 32, 99, 111, 110, 116, 97, 105,
110, 32, 97, 32, 39, 112, 97, 100, 32, 102, 105, 108, 101, 39, 32, 100, 105, 114, 101, 99, 116, 111, 114, 121, 46,
32, 84, 104, 105, 115, 32, 100, 105, 114, 101, 99, 116, 111, 114, 121, 32, 97, 110, 100, 32, 116, 104, 101, 32, 102,
105, 108, 101, 115, 32, 119, 105, 116, 104, 105, 110, 32, 105, 116, 32, 109, 97, 121, 32, 98, 101, 32, 101, 114, 97,
115, 101, 100, 32, 111, 110, 99, 101, 32, 114, 101, 116, 114, 105, 101, 118, 97, 108, 32, 99, 111, 109, 112, 108,
101, 116, 101, 115, 46, 10, 78, 111, 116, 101, 58, 32, 116, 104, 101, 32, 102, 105, 108, 101, 32, 114, 97, 112, 112,
112, 105, 100, 45, 119, 101, 105, 103, 104, 116, 115, 46, 116, 97, 114, 95, 109, 101, 116, 97, 46, 120, 109, 108, 32,
99, 111, 110, 116, 97, 105, 110, 115, 32, 109, 101, 116, 97, 100, 97, 116, 97, 32, 97, 98, 111, 117, 116, 32, 116,
104, 105, 115, 32, 116, 111, 114, 114, 101, 110, 116, 39, 115, 32, 99, 111, 110, 116, 101, 110, 116, 115, 46, 49, 48,
58, 99, 114, 101, 97, 116, 101, 100, 32, 98, 121, 49, 53, 58, 105, 97, 95, 109, 97, 107, 101, 95, 116, 111, 114, 114,
101, 110, 116, 49, 51, 58, 99, 114, 101, 97, 116, 105, 111, 110, 32, 100, 97, 116, 101, 105, 49, 54, 56, 57, 50, 55,
51, 55, 56, 55, 101, 52, 58, 105, 110, 102, 111, 100, 49, 49, 58, 99, 111, 108, 108, 101, 99, 116, 105, 111, 110,
115, 108, 51, 49, 58, 111, 114, 103, 46, 97, 114, 99, 104, 105, 118, 101, 46, 114, 97, 112, 112, 112, 105, 100, 45,
119, 101, 105, 103, 104, 116, 115, 46, 116, 97, 114, 101, 53, 58, 102, 105, 108, 101, 115, 108, 100, 53, 58, 99, 114,
99, 51, 50, 56, 58, 53, 55, 100, 51, 51, 102, 99, 99, 54, 58, 108, 101, 110, 103, 116, 104, 105, 49, 49, 53, 50, 56,
51, 50, 52, 101, 51, 58, 109, 100, 53, 51, 50, 58, 101, 57, 49, 98, 98, 52, 98, 97, 56, 50, 54, 57, 53, 49, 54, 49,
98, 101, 54, 56, 102, 56, 98, 51, 51, 97, 101, 55, 54, 49, 52, 50, 53, 58, 109, 116, 105, 109, 101, 49, 48, 58, 49,
54, 56, 57, 50, 55, 51, 55, 51, 48, 52, 58, 112, 97, 116, 104, 108, 50, 50, 58, 82, 65, 80, 80, 80, 73, 68, 32, 87,
101, 105, 103, 104, 116, 115, 46, 116, 97, 114, 46, 103, 122, 101, 52, 58, 115, 104, 97, 49, 52, 48, 58, 52, 53, 57,
55, 48, 101, 102, 51, 51, 99, 98, 51, 48, 52, 57, 97, 55, 97, 56, 54, 50, 57, 101, 52, 48, 99, 56, 102, 53, 101, 53,
50, 54, 56, 100, 49, 100, 99, 53, 51, 101, 100, 53, 58, 99, 114, 99, 51, 50, 56, 58, 99, 54, 53, 56, 102, 100, 52,
102, 54, 58, 108, 101, 110, 103, 116, 104, 105, 50, 48, 52, 56, 48, 101, 51, 58, 109, 100, 53, 51, 50, 58, 97, 55,
56, 50, 98, 50, 97, 53, 51, 98, 97, 52, 57, 102, 48, 100, 52, 53, 102, 51, 100, 100, 54, 101, 51, 53, 101, 48, 100,
53, 57, 51, 53, 58, 109, 116, 105, 109, 101, 49, 48, 58, 49, 54, 56, 57, 50, 55, 51, 55, 56, 51, 52, 58, 112, 97,
116, 104, 108, 51, 49, 58, 114, 97, 112, 112, 112, 105, 100, 45, 119, 101, 105, 103, 104, 116, 115, 46, 116, 97, 114,
95, 109, 101, 116, 97, 46, 115, 113, 108, 105, 116, 101, 101, 52, 58, 115, 104, 97, 49, 52, 48, 58, 98, 99, 98, 48,
54, 98, 51, 49, 54, 52, 102, 49, 100, 50, 97, 98, 97, 50, 50, 101, 102, 54, 48, 52, 54, 101, 98, 56, 48, 102, 54, 53,
50, 54, 52, 101, 57, 102, 98, 97, 101, 100, 53, 58, 99, 114, 99, 51, 50, 56, 58, 56, 49, 52, 48, 97, 53, 99, 55, 54,
58, 108, 101, 110, 103, 116, 104, 105, 49, 48, 52, 52, 101, 51, 58, 109, 100, 53, 51, 50, 58, 49, 98, 97, 98, 50, 49,
101, 53, 48, 101, 48, 54, 97, 98, 52, 50, 100, 51, 97, 55, 55, 100, 56, 55, 50, 98, 102, 50, 53, 50, 101, 53, 53, 58,
109, 116, 105, 109, 101, 49, 48, 58, 49, 54, 56, 57, 50, 55, 51, 55, 54, 51, 52, 58, 112, 97, 116, 104, 108, 50, 56,
58, 114, 97, 112, 112, 112, 105, 100, 45, 119, 101, 105, 103, 104, 116, 115, 46, 116, 97, 114, 95, 109, 101, 116, 97,
46, 120, 109, 108, 101, 52, 58, 115, 104, 97, 49, 52, 48, 58, 98, 50, 102, 48, 102, 50, 98, 98, 101, 99, 51, 52, 97,
97, 57, 49, 52, 48, 102, 98, 57, 97, 99, 51, 102, 99, 98, 49, 57, 48, 53, 56, 56, 97, 52, 57, 54, 97, 97, 51, 101,
101, 52, 58, 110, 97, 109, 101, 49, 57, 58, 114, 97, 112, 112, 112, 105, 100, 45, 119, 101, 105, 103, 104, 116, 115,
46, 116, 97, 114, 49, 50, 58, 112, 105, 101, 99, 101, 32, 108, 101, 110, 103, 116, 104, 105, 53, 50, 52, 50, 56, 56,
101, 54, 58, 112, 105, 101, 99, 101, 115, 52, 54, 48, 58, 171, 236, 85, 110, 15, 123, 231, 211, 48, 12, 246, 104,
140, 144, 109, 153, 12, 62, 50, 181, 44, 242, 182, 124, 12, 50, 82, 188, 114, 111, 7, 30, 115, 171, 118, 241, 188,
50, 43, 252, 33, 212, 127, 26, 233, 114, 53, 64, 126, 195, 180, 137, 9, 43, 237, 75, 216, 176, 108, 101, 140, 39, 88,
174, 251, 114, 117, 115, 68, 55, 136, 40, 32, 210, 148, 189, 164, 106, 248, 210, 166, 253, 2, 101, 28, 28, 223, 184,
86, 109, 58, 210, 126, 167, 61, 202, 226, 73, 247, 54, 141, 23, 119, 110, 50, 173, 239, 165, 68, 194, 143, 182, 156,
36, 86, 173, 232, 251, 123, 166, 113, 192, 129, 229, 67, 3, 145, 212, 79, 176, 166, 100, 202, 41, 27, 13, 29, 64,
125, 57, 78, 118, 150, 235, 1, 24, 243, 245, 80, 142, 47, 250, 84, 252, 73, 102, 133, 216, 56, 135, 120, 155, 10,
143, 122, 163, 44, 143, 114, 54, 173, 109, 116, 11, 252, 197, 87, 113, 134, 251, 243, 207, 202, 201, 218, 236, 97,
98, 162, 42, 27, 167, 133, 137, 145, 143, 170, 192, 192, 203, 13, 87, 216, 183, 231, 100, 77, 242, 132, 115, 118,
152, 251, 58, 23, 72, 215, 156, 1, 254, 202, 109, 31, 197, 151, 52, 5, 84, 57, 218, 194, 110, 23, 65, 17, 105, 243,
70, 209, 125, 22, 211, 192, 135, 59, 195, 178, 12, 29, 224, 226, 73, 195, 5, 210, 76, 0, 90, 91, 120, 1, 18, 62, 191,
82, 67, 73, 109, 26, 238, 35, 121, 210, 14, 40, 182, 132, 126, 197, 237, 121, 222, 100, 2, 237, 71, 113, 61, 147, 22,
196, 162, 118, 24, 119, 84, 197, 49, 72, 150, 58, 81, 193, 74, 146, 144, 145, 243, 207, 72, 91, 36, 134, 85, 168,
235, 12, 198, 45, 134, 226, 41, 86, 9, 44, 56, 11, 205, 193, 202, 69, 230, 100, 106, 71, 254, 187, 46, 71, 154, 119,
69, 41, 233, 114, 25, 32, 111, 66, 121, 43, 55, 185, 83, 37, 237, 15, 41, 4, 213, 226, 150, 241, 222, 207, 153, 190,
50, 170, 184, 10, 29, 11, 159, 185, 214, 171, 92, 80, 67, 120, 133, 65, 9, 1, 36, 207, 224, 137, 118, 91, 77, 169,
202, 114, 192, 223, 146, 71, 15, 13, 206, 202, 150, 198, 126, 165, 65, 95, 43, 167, 187, 4, 204, 247, 68, 127, 148,
30, 36, 210, 27, 23, 202, 24, 121, 144, 163, 214, 32, 117, 162, 150, 104, 6, 88, 90, 222, 245, 44, 26, 144, 34, 114,
51, 142, 213, 178, 168, 250, 229, 233, 231, 105, 98, 2, 124, 9, 179, 76, 101, 54, 58, 108, 111, 99, 97, 108, 101, 50,
58, 101, 110, 53, 58, 116, 105, 116, 108, 101, 49, 57, 58, 114, 97, 112, 112, 112, 105, 100, 45, 119, 101, 105, 103,
104, 116, 115, 46, 116, 97, 114, 56, 58, 117, 114, 108, 45, 108, 105, 115, 116, 108, 50, 57, 58, 104, 116, 116, 112,
115, 58, 47, 47, 97, 114, 99, 104, 105, 118, 101, 46, 111, 114, 103, 47, 100, 111, 119, 110, 108, 111, 97, 100, 47,
52, 48, 58, 104, 116, 116, 112, 58, 47, 47, 105, 97, 57, 48, 50, 55, 48, 50, 46, 117, 115, 46, 97, 114, 99, 104, 105,
118, 101, 46, 111, 114, 103, 47, 50, 50, 47, 105, 116, 101, 109, 115, 47, 52, 48, 58, 104, 116, 116, 112, 58, 47, 47,
105, 97, 56, 48, 50, 55, 48, 50, 46, 117, 115, 46, 97, 114, 99, 104, 105, 118, 101, 46, 111, 114, 103, 47, 50, 50,
47, 105, 116, 101, 109, 115, 47, 101, 101,
]
.to_vec()
}
#[test]
fn it_should_calculate_the_original_info_hash_using_all_fields_in_the_info_key_dictionary() {
let original_info_hash = super::calculate_info_hash(&torrent_with_custom_info_dict_key()).unwrap();
assert_eq!(
original_info_hash,
InfoHash::from_str("6c690018c5786dbbb00161f62b0712d69296df97").unwrap() );
}
#[test]
fn it_should_calculate_the_new_info_hash_ignoring_non_standard_fields_in_the_info_key_dictionary() {
let torrent = super::decode_torrent(&torrent_with_custom_info_dict_key()).unwrap();
assert_eq!(
torrent.canonical_info_hash_hex(),
"8aa01a4c816332045ffec83247ccbc654547fedf".to_string() );
}
}