Skip to content

Commit

Permalink
test(http): [torrust#159] add test for invalid announce request params
Browse files Browse the repository at this point in the history
  • Loading branch information
josecelano committed Jan 24, 2023
1 parent 62dbffa commit 8ae4928
Show file tree
Hide file tree
Showing 4 changed files with 219 additions and 10 deletions.
12 changes: 12 additions & 0 deletions tests/common/fixtures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,15 @@ fn default_peer_for_testing() -> Peer {
event: AnnounceEvent::Started,
}
}

pub fn invalid_info_hashes() -> Vec<String> {
[
"0".to_string(),
"-1".to_string(),
"1.1".to_string(),
"INVALID INFOHASH".to_string(),
"9c38422213e30bff212b30c360d26f9a0213642".to_string(), // 39-char length instead of 40
"9c38422213e30bff212b30c360d26f9a0213642&".to_string(), // Invalid char
]
.to_vec()
}
17 changes: 16 additions & 1 deletion tests/http/requests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ pub type ByteArray20 = [u8; 20];
pub type PortNumber = u16;

pub enum Event {
//tarted,
//Started,
//Stopped,
Completed,
}
Expand Down Expand Up @@ -227,4 +227,19 @@ impl AnnounceQueryParams {
self.event = None;
self.compact = None;
}

pub fn set(&mut self, param_name: &str, param_value: &str) {
match param_name {
"info_hash" => self.info_hash = Some(param_value.to_string()),
"peer_addr" => self.peer_addr = Some(param_value.to_string()),
"downloaded" => self.downloaded = Some(param_value.to_string()),
"uploaded" => self.uploaded = Some(param_value.to_string()),
"peer_id" => self.peer_id = Some(param_value.to_string()),
"port" => self.port = Some(param_value.to_string()),
"left" => self.left = Some(param_value.to_string()),
"event" => self.event = Some(param_value.to_string()),
"compact" => self.compact = Some(param_value.to_string()),
&_ => panic!("Invalid param name for announce query"),
}
}
}
188 changes: 188 additions & 0 deletions tests/http_tracker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ mod http_tracker_server {
mod for_all_config_modes {

mod receiving_an_announce_request {
use crate::common::fixtures::invalid_info_hashes;
use crate::http::asserts::{
assert_internal_server_error_response, assert_invalid_info_hash_error_response,
assert_invalid_peer_id_error_response, assert_is_announce_response,
Expand Down Expand Up @@ -81,6 +82,193 @@ mod http_tracker_server {

assert_internal_server_error_response(response).await;
}

#[tokio::test]
async fn should_fail_when_the_info_hash_param_is_invalid() {
let http_tracker_server = start_default_http_tracker().await;

let mut params = AnnounceQueryBuilder::default().query().params();

for invalid_value in &invalid_info_hashes() {
params.set("info_hash", invalid_value);

let response = Client::new(http_tracker_server.get_connection_info())
.get(&format!("announce?{params}"))
.await;

assert_invalid_info_hash_error_response(response).await;
}
}

#[tokio::test]
async fn should_not_fail_when_the_peer_address_param_is_invalid() {
// AnnounceQuery does not even contain the `peer_addr`
// The peer IP is obtained in two ways:
// 1. If tracker is NOT running `on_reverse_proxy` from the remote client IP if there.
// 2. If tracker is running `on_reverse_proxy` from `X-Forwarded-For` request header is tracker is running `on_reverse_proxy`.

let http_tracker_server = start_default_http_tracker().await;

let mut params = AnnounceQueryBuilder::default().query().params();

params.peer_addr = Some("INVALID-IP-ADDRESS".to_string());

let response = Client::new(http_tracker_server.get_connection_info())
.get(&format!("announce?{params}"))
.await;

assert_is_announce_response(response).await;
}

#[tokio::test]
async fn should_fail_when_the_downloaded_param_is_invalid() {
let http_tracker_server = start_default_http_tracker().await;

let mut params = AnnounceQueryBuilder::default().query().params();

let invalid_values = ["-1", "1.1", "a"];

for invalid_value in invalid_values {
params.set("downloaded", invalid_value);

let response = Client::new(http_tracker_server.get_connection_info())
.get(&format!("announce?{params}"))
.await;

assert_internal_server_error_response(response).await;
}
}

#[tokio::test]
async fn should_fail_when_the_uploaded_param_is_invalid() {
let http_tracker_server = start_default_http_tracker().await;

let mut params = AnnounceQueryBuilder::default().query().params();

let invalid_values = ["-1", "1.1", "a"];

for invalid_value in invalid_values {
params.set("uploaded", invalid_value);

let response = Client::new(http_tracker_server.get_connection_info())
.get(&format!("announce?{params}"))
.await;

assert_internal_server_error_response(response).await;
}
}

#[tokio::test]
async fn should_fail_when_the_peer_id_param_is_invalid() {
let http_tracker_server = start_default_http_tracker().await;

let mut params = AnnounceQueryBuilder::default().query().params();

let invalid_values = [
"0",
"-1",
"1.1",
"a",
"-qB0000000000000000", // 19 bytes
"-qB000000000000000000", // 21 bytes
];

for invalid_value in invalid_values {
params.set("peer_id", invalid_value);

let response = Client::new(http_tracker_server.get_connection_info())
.get(&format!("announce?{params}"))
.await;

assert_invalid_peer_id_error_response(response).await;
}
}

#[tokio::test]
async fn should_fail_when_the_port_param_is_invalid() {
let http_tracker_server = start_default_http_tracker().await;

let mut params = AnnounceQueryBuilder::default().query().params();

let invalid_values = ["-1", "1.1", "a"];

for invalid_value in invalid_values {
params.set("port", invalid_value);

let response = Client::new(http_tracker_server.get_connection_info())
.get(&format!("announce?{params}"))
.await;

assert_internal_server_error_response(response).await;
}
}

#[tokio::test]
async fn should_fail_when_the_left_param_is_invalid() {
let http_tracker_server = start_default_http_tracker().await;

let mut params = AnnounceQueryBuilder::default().query().params();

let invalid_values = ["-1", "1.1", "a"];

for invalid_value in invalid_values {
params.set("left", invalid_value);

let response = Client::new(http_tracker_server.get_connection_info())
.get(&format!("announce?{params}"))
.await;

assert_internal_server_error_response(response).await;
}
}

#[tokio::test]
async fn should_not_fail_when_the_event_param_is_invalid() {
// All invalid values are ignored as if the `event` param was empty

let http_tracker_server = start_default_http_tracker().await;

let mut params = AnnounceQueryBuilder::default().query().params();

let invalid_values = [
"0",
"-1",
"1.1",
"a",
"Started", // It should be lowercase
"Stopped", // It should be lowercase
"Completed", // It should be lowercase
];

for invalid_value in invalid_values {
params.set("event", invalid_value);

let response = Client::new(http_tracker_server.get_connection_info())
.get(&format!("announce?{params}"))
.await;

assert_is_announce_response(response).await;
}
}

#[tokio::test]
async fn should_not_fail_when_the_compact_param_is_invalid() {
let http_tracker_server = start_default_http_tracker().await;

let mut params = AnnounceQueryBuilder::default().query().params();

let invalid_values = ["-1", "1.1", "a"];

for invalid_value in invalid_values {
params.set("compact", invalid_value);

let response = Client::new(http_tracker_server.get_connection_info())
.get(&format!("announce?{params}"))
.await;

assert_internal_server_error_response(response).await;
}
}
}

mod receiving_an_scrape_request {
Expand Down
12 changes: 3 additions & 9 deletions tests/tracker_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,12 @@ mod common;

mod tracker_apis {

use crate::common::fixtures::invalid_info_hashes;

// When these infohashes are used in URL path params
// the response is a custom response returned in the handler
fn invalid_infohashes_returning_bad_request() -> Vec<String> {
[
"0".to_string(),
"-1".to_string(),
"1.1".to_string(),
"INVALID INFOHASH".to_string(),
"9c38422213e30bff212b30c360d26f9a0213642".to_string(), // 39-char length instead of 40
"9c38422213e30bff212b30c360d26f9a0213642&".to_string(), // Invalid char
]
.to_vec()
invalid_info_hashes()
}

// When these infohashes are used in URL path params
Expand Down

0 comments on commit 8ae4928

Please sign in to comment.