Skip to content

Commit

Permalink
fix(http): Display impl for tracker::peer:ID
Browse files Browse the repository at this point in the history
```
peer::Id(*b"-qB00000000000000000").to_string()
```

was always returning an empty string.

It has been changed to return the Hex representations of the byte array.
  • Loading branch information
josecelano committed Jan 27, 2023
1 parent e1765f3 commit fcd60e2
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 13 deletions.
2 changes: 1 addition & 1 deletion src/apis/resources/peer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub struct Id {
impl From<tracker::peer::Id> for Id {
fn from(peer_id: tracker::peer::Id) -> Self {
Id {
id: peer_id.get_id(),
id: peer_id.to_hex_string(),
client: peer_id.get_client_name().map(std::string::ToString::to_string),
}
}
Expand Down
56 changes: 44 additions & 12 deletions src/tracker/peer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,25 +93,45 @@ pub struct Id(pub [u8; 20]);

impl std::fmt::Display for Id {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut buffer = [0u8; 20];
let bytes_out = binascii::bin2hex(&self.0, &mut buffer).ok();
match bytes_out {
Some(bytes) => write!(f, "{}", std::str::from_utf8(bytes).unwrap()),
match self.to_hex_string() {
Some(hex) => write!(f, "{hex}"),
None => write!(f, ""),
}
}
}

impl Id {
#[must_use]
/// Converts to hex string.
///
/// For the Id `-qB00000000000000000` ti returns `2d71423030303030303030303030303030303030`
///
/// For example:
///
///```text
/// Bytes = Hex
/// -qB00000000000000000 = 2d71423030303030303030303030303030303030
/// -qB00000000000000000 = 2d 71 42 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30
///
/// -------------
/// |Char | Hex |
/// -------------
/// | - | 2D |
/// | q | 71 |
/// | B | 42 |
/// | 0 | 30 |
/// -------------
/// ```
///
/// Return `None` is some of the bytes are invalid UTF8 values.
///
/// # Panics
///
/// It will panic if the `binascii::bin2hex` from a too-small output buffer.
pub fn get_id(&self) -> Option<String> {
pub fn to_hex_string(&self) -> Option<String> {
let buff_size = self.0.len() * 2;
let mut tmp: Vec<u8> = vec![0; buff_size];
binascii::bin2hex(&self.0, &mut tmp).unwrap();

std::str::from_utf8(&tmp).ok().map(std::string::ToString::to_string)
}

Expand Down Expand Up @@ -206,7 +226,7 @@ impl Serialize for Id {
}

let obj = PeerIdInfo {
id: self.get_id(),
id: self.to_hex_string(),
client: self.get_client_name(),
};
obj.serialize(serializer)
Expand All @@ -220,13 +240,25 @@ mod test {
use crate::tracker::peer;

#[test]
fn should_be_converted_into_string() {
// todo: it seems it's not working
fn should_be_converted_to_hex_string() {
let id = peer::Id(*b"-qB00000000000000000");
assert_eq!(id.to_hex_string().unwrap(), "2d71423030303030303030303030303030303030");

let id = peer::Id([
0, 159, 146, 150, 0, 159, 146, 150, 0, 159, 146, 150, 0, 159, 146, 150, 0, 159, 146, 150,
]);
assert_eq!(id.to_hex_string().unwrap(), "009f9296009f9296009f9296009f9296009f9296");
}

#[test]
fn should_be_converted_into_string_type_using_the_hex_string_format() {
let id = peer::Id(*b"-qB00000000000000000");
assert_eq!(id.to_string(), "");
assert_eq!(id.to_string(), "2d71423030303030303030303030303030303030");

let id = peer::Id(*b"-qB00000000000000001");
assert_eq!(id.to_string(), "");
let id = peer::Id([
0, 159, 146, 150, 0, 159, 146, 150, 0, 159, 146, 150, 0, 159, 146, 150, 0, 159, 146, 150,
]);
assert_eq!(id.to_string(), "009f9296009f9296009f9296009f9296009f9296");
}
}

Expand Down
70 changes: 70 additions & 0 deletions tests/http_tracker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,19 @@ mod common;
mod http;

mod http_tracker_server {
use std::str::FromStr;

use percent_encoding::NON_ALPHANUMERIC;
use torrust_tracker::protocol::info_hash::InfoHash;

#[test]
fn calculate_info_hash_param() {
let info_hash = InfoHash::from_str("3b245504cf5f11bbdbe1201cea6a6bf45aee1bc0").unwrap();

let param = percent_encoding::percent_encode(&info_hash.0, NON_ALPHANUMERIC).to_string();

assert_eq!(param, "%3B%24U%04%CF%5F%11%BB%DB%E1%20%1C%EAjk%F4Z%EE%1B%C0");
}

mod for_all_config_modes {

Expand Down Expand Up @@ -796,3 +809,60 @@ mod http_tracker_server {
mod receiving_an_scrape_request {}
}
}

mod percent_encoding {
// todo: these operations are used in the HTTP tracker but they have not been extracted into independent functions.
// These tests document the operations. This behavior could be move to some functions int he future if they are extracted.

use std::str::FromStr;

use percent_encoding::NON_ALPHANUMERIC;
use torrust_tracker::protocol::info_hash::InfoHash;
use torrust_tracker::tracker::peer;

#[test]
fn how_to_encode_an_info_hash() {
let info_hash = InfoHash::from_str("3b245504cf5f11bbdbe1201cea6a6bf45aee1bc0").unwrap();

let encoded_info_hash = percent_encoding::percent_encode(&info_hash.0, NON_ALPHANUMERIC).to_string();

assert_eq!(encoded_info_hash, "%3B%24U%04%CF%5F%11%BB%DB%E1%20%1C%EAjk%F4Z%EE%1B%C0");
}

#[test]
fn how_to_decode_an_info_hash() {
let encoded_infohash = "%3B%24U%04%CF%5F%11%BB%DB%E1%20%1C%EAjk%F4Z%EE%1B%C0";

let info_hash_bytes = percent_encoding::percent_decode_str(encoded_infohash).collect::<Vec<u8>>();
let info_hash = InfoHash::from_str(&hex::encode(info_hash_bytes)).unwrap();

assert_eq!(
info_hash,
InfoHash::from_str("3b245504cf5f11bbdbe1201cea6a6bf45aee1bc0").unwrap()
);
}

#[test]
fn how_to_encode_a_peer_id() {
let peer_id = peer::Id(*b"-qB00000000000000000");

let encoded_peer_id = percent_encoding::percent_encode(&peer_id.0, NON_ALPHANUMERIC).to_string();

assert_eq!(encoded_peer_id, "%2DqB00000000000000000");
}

#[test]
fn how_to_decode_a_peer_id() {
let encoded_peer_id = "%2DqB00000000000000000";

let bytes_vec = percent_encoding::percent_decode_str(encoded_peer_id).collect::<Vec<u8>>();

// Clone peer_id_bytes into fixed length array
let mut peer_id_bytes: [u8; 20] = Default::default();
peer_id_bytes.clone_from_slice(bytes_vec.as_slice());

let peer_id = peer::Id(peer_id_bytes);

assert_eq!(peer_id, peer::Id(*b"-qB00000000000000000"));
}
}

0 comments on commit fcd60e2

Please sign in to comment.