Skip to content

Commit b403382

Browse files
committed
Merge #1180: Refactor: Move logic to http-protocol and primitives packages
c2d134e test: re-enable slow tests (Jose Celano) a7ceb0f refactor: [#1140] move http tracker logic to http-protocol and primitives packages (Jose Celano) Pull request description: Refactor: Move logic to `http-protocol` and `primitives` packages. This will: - Allow sharing that code with other projects. - Allow re-enabling doc tests disabled [here](#1097). - Decouple generic reusable logic from Axum framework. - Improve compilation times. ACKs for top commit: josecelano: ACK c2d134e Tree-SHA512: 00c49567aed10f23e525219a26765ca2e8ce948037785da7622076e7d6de981983cbf3c88f6043631ac7bfc2def2d3161dc954a8f77746c4be48595d09af49ad
2 parents f508ef7 + c2d134e commit b403382

35 files changed

+258
-261
lines changed

Cargo.lock

+9-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

-2
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ http-body = "1"
5858
hyper = "1"
5959
hyper-util = { version = "0", features = ["http1", "http2", "tokio"] }
6060
lazy_static = "1"
61-
multimap = "0"
6261
parking_lot = "0"
6362
percent-encoding = "2"
6463
pin-project-lite = "0"
@@ -79,7 +78,6 @@ thiserror = "2"
7978
tokio = { version = "1", features = ["macros", "net", "rt-multi-thread", "signal", "sync"] }
8079
torrust-tracker-clock = { version = "3.0.0-develop", path = "packages/clock" }
8180
torrust-tracker-configuration = { version = "3.0.0-develop", path = "packages/configuration" }
82-
torrust-tracker-contrib-bencode = { version = "3.0.0-develop", path = "contrib/bencode" }
8381
torrust-tracker-located-error = { version = "3.0.0-develop", path = "packages/located-error" }
8482
torrust-tracker-primitives = { version = "3.0.0-develop", path = "packages/primitives" }
8583
torrust-tracker-torrent-repository = { version = "3.0.0-develop", path = "packages/torrent-repository" }

packages/http-protocol/Cargo.toml

+8
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,13 @@ version.workspace = true
1717
[dependencies]
1818
aquatic_udp_protocol = "0"
1919
bittorrent-primitives = "0.1.0"
20+
derive_more = { version = "1", features = ["as_ref", "constructor", "from"] }
21+
multimap = "0"
2022
percent-encoding = "2"
23+
serde = { version = "1", features = ["derive"] }
24+
serde_bencode = "0"
25+
thiserror = "2"
26+
torrust-tracker-configuration = { version = "3.0.0-develop", path = "../configuration" }
27+
torrust-tracker-contrib-bencode = { version = "3.0.0-develop", path = "../../contrib/bencode" }
28+
torrust-tracker-located-error = { version = "3.0.0-develop", path = "../located-error" }
2129
torrust-tracker-primitives = { version = "3.0.0-develop", path = "../primitives" }

packages/http-protocol/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
//! Primitive types and function for `BitTorrent` HTTP trackers.
22
pub mod percent_encoding;
3+
pub mod v1;

packages/http-protocol/src/v1/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
pub mod query;
2+
pub mod requests;
3+
pub mod responses;
4+
pub mod services;

src/servers/http/v1/query.rs packages/http-protocol/src/v1/query.rs

+12-12
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ impl Query {
3030
/// It return `Some(value)` for a URL query param if the param with the
3131
/// input `name` exists. For example:
3232
///
33-
/// ```text
34-
/// use torrust_tracker_lib::servers::http::v1::query::Query;
33+
/// ```rust
34+
/// use bittorrent_http_protocol::v1::query::Query;
3535
///
3636
/// let raw_query = "param1=value1&param2=value2";
3737
///
@@ -43,8 +43,8 @@ impl Query {
4343
///
4444
/// It returns only the first param value even if it has multiple values:
4545
///
46-
/// ```text
47-
/// use torrust_tracker_lib::servers::http::v1::query::Query;
46+
/// ```rust
47+
/// use bittorrent_http_protocol::v1::query::Query;
4848
///
4949
/// let raw_query = "param1=value1&param1=value2";
5050
///
@@ -59,8 +59,8 @@ impl Query {
5959

6060
/// Returns all the param values as a vector.
6161
///
62-
/// ```text
63-
/// use torrust_tracker_lib::servers::http::v1::query::Query;
62+
/// ```rust
63+
/// use bittorrent_http_protocol::v1::query::Query;
6464
///
6565
/// let query = "param1=value1&param1=value2".parse::<Query>().unwrap();
6666
///
@@ -72,8 +72,8 @@ impl Query {
7272
///
7373
/// Returns all the param values as a vector even if it has only one value.
7474
///
75-
/// ```text
76-
/// use torrust_tracker_lib::servers::http::v1::query::Query;
75+
/// ```rust
76+
/// use bittorrent_http_protocol::v1::query::Query;
7777
///
7878
/// let query = "param1=value1".parse::<Query>().unwrap();
7979
///
@@ -224,7 +224,7 @@ impl std::fmt::Display for FieldValuePairSet {
224224
mod tests {
225225

226226
mod url_query {
227-
use crate::servers::http::v1::query::Query;
227+
use crate::v1::query::Query;
228228

229229
#[test]
230230
fn should_parse_the_query_params_from_an_url_query_string() {
@@ -277,7 +277,7 @@ mod tests {
277277
}
278278

279279
mod should_allow_more_than_one_value_for_the_same_param {
280-
use crate::servers::http::v1::query::Query;
280+
use crate::v1::query::Query;
281281

282282
#[test]
283283
fn instantiated_from_a_vector() {
@@ -299,7 +299,7 @@ mod tests {
299299
}
300300

301301
mod should_be_displayed {
302-
use crate::servers::http::v1::query::Query;
302+
use crate::v1::query::Query;
303303

304304
#[test]
305305
fn with_one_param() {
@@ -320,7 +320,7 @@ mod tests {
320320
}
321321

322322
mod param_name_value_pair {
323-
use crate::servers::http::v1::query::NameValuePair;
323+
use crate::v1::query::NameValuePair;
324324

325325
#[test]
326326
fn should_parse_a_single_query_param() {

src/servers/http/v1/requests/announce.rs packages/http-protocol/src/v1/requests/announce.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ use std::panic::Location;
66
use std::str::FromStr;
77

88
use aquatic_udp_protocol::{NumberOfBytes, PeerId};
9-
use bittorrent_http_protocol::percent_encoding::{percent_decode_info_hash, percent_decode_peer_id};
109
use bittorrent_primitives::info_hash::{self, InfoHash};
1110
use thiserror::Error;
1211
use torrust_tracker_located_error::{Located, LocatedError};
1312
use torrust_tracker_primitives::peer;
1413

15-
use crate::servers::http::v1::query::{ParseQueryError, Query};
16-
use crate::servers::http::v1::responses;
14+
use crate::percent_encoding::{percent_decode_info_hash, percent_decode_peer_id};
15+
use crate::v1::query::{ParseQueryError, Query};
16+
use crate::v1::responses;
1717

1818
// Query param names
1919
const INFO_HASH: &str = "info_hash";
@@ -29,9 +29,9 @@ const NUMWANT: &str = "numwant";
2929
/// The `Announce` request. Fields use the domain types after parsing the
3030
/// query params of the request.
3131
///
32-
/// ```text
32+
/// ```rust
3333
/// use aquatic_udp_protocol::{NumberOfBytes, PeerId};
34-
/// use torrust_tracker_lib::servers::http::v1::requests::announce::{Announce, Compact, Event};
34+
/// use bittorrent_http_protocol::v1::requests::announce::{Announce, Compact, Event};
3535
/// use bittorrent_primitives::info_hash::InfoHash;
3636
///
3737
/// let request = Announce {
@@ -381,8 +381,8 @@ mod tests {
381381
use aquatic_udp_protocol::{NumberOfBytes, PeerId};
382382
use bittorrent_primitives::info_hash::InfoHash;
383383

384-
use crate::servers::http::v1::query::Query;
385-
use crate::servers::http::v1::requests::announce::{
384+
use crate::v1::query::Query;
385+
use crate::v1::requests::announce::{
386386
Announce, Compact, Event, COMPACT, DOWNLOADED, EVENT, INFO_HASH, LEFT, NUMWANT, PEER_ID, PORT, UPLOADED,
387387
};
388388

@@ -452,8 +452,8 @@ mod tests {
452452

453453
mod when_it_is_instantiated_from_the_url_query_params {
454454

455-
use crate::servers::http::v1::query::Query;
456-
use crate::servers::http::v1::requests::announce::{
455+
use crate::v1::query::Query;
456+
use crate::v1::requests::announce::{
457457
Announce, COMPACT, DOWNLOADED, EVENT, INFO_HASH, LEFT, NUMWANT, PEER_ID, PORT, UPLOADED,
458458
};
459459

src/servers/http/v1/requests/scrape.rs packages/http-protocol/src/v1/requests/scrape.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
//! Data structures and logic for parsing the `scrape` request.
44
use std::panic::Location;
55

6-
use bittorrent_http_protocol::percent_encoding::percent_decode_info_hash;
76
use bittorrent_primitives::info_hash::{self, InfoHash};
87
use thiserror::Error;
98
use torrust_tracker_located_error::{Located, LocatedError};
109

11-
use crate::servers::http::v1::query::Query;
12-
use crate::servers::http::v1::responses;
10+
use crate::percent_encoding::percent_decode_info_hash;
11+
use crate::v1::query::Query;
12+
use crate::v1::responses;
1313

1414
// Query param names
1515
const INFO_HASH: &str = "info_hash";
@@ -86,8 +86,8 @@ mod tests {
8686

8787
use bittorrent_primitives::info_hash::InfoHash;
8888

89-
use crate::servers::http::v1::query::Query;
90-
use crate::servers::http::v1::requests::scrape::{Scrape, INFO_HASH};
89+
use crate::v1::query::Query;
90+
use crate::v1::requests::scrape::{Scrape, INFO_HASH};
9191

9292
#[test]
9393
fn should_be_instantiated_from_the_url_query_with_only_one_infohash() {
@@ -107,8 +107,8 @@ mod tests {
107107

108108
mod when_it_is_instantiated_from_the_url_query_params {
109109

110-
use crate::servers::http::v1::query::Query;
111-
use crate::servers::http::v1::requests::scrape::{Scrape, INFO_HASH};
110+
use crate::v1::query::Query;
111+
use crate::v1::requests::scrape::{Scrape, INFO_HASH};
112112

113113
#[test]
114114
fn it_should_fail_if_the_query_does_not_include_the_info_hash_param() {

src/servers/http/v1/responses/announce.rs packages/http-protocol/src/v1/responses/announce.rs

+11-33
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,14 @@
1-
//! `Announce` response for the HTTP tracker [`announce`](crate::servers::http::v1::requests::announce::Announce) request.
1+
//! `Announce` response for the HTTP tracker [`announce`](bittorrent_http_protocol::v1::requests::announce::Announce) request.
22
//!
33
//! Data structures and logic to build the `announce` response.
44
use std::io::Write;
55
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
66

7-
use axum::http::StatusCode;
87
use derive_more::{AsRef, Constructor, From};
98
use torrust_tracker_contrib_bencode::{ben_bytes, ben_int, ben_list, ben_map, BMutAccess, BencodeMut};
9+
use torrust_tracker_primitives::core::AnnounceData;
1010
use torrust_tracker_primitives::peer;
1111

12-
use super::Response;
13-
use crate::core::AnnounceData;
14-
use crate::servers::http::v1::responses;
15-
1612
/// An [`Announce`] response, that can be anything that is convertible from [`AnnounceData`].
1713
///
1814
/// The [`Announce`] can built from any data that implements: [`From<AnnounceData>`] and [`Into<Vec<u8>>`].
@@ -35,7 +31,7 @@ pub struct Announce<E>
3531
where
3632
E: From<AnnounceData> + Into<Vec<u8>>,
3733
{
38-
data: E,
34+
pub data: E,
3935
}
4036

4137
/// Build any [`Announce`] from an [`AnnounceData`].
@@ -45,24 +41,6 @@ impl<E: From<AnnounceData> + Into<Vec<u8>>> From<AnnounceData> for Announce<E> {
4541
}
4642
}
4743

48-
/// Convert any Announce [`Announce`] into a [`axum::response::Response`]
49-
impl<E: From<AnnounceData> + Into<Vec<u8>>> axum::response::IntoResponse for Announce<E>
50-
where
51-
Announce<E>: Response,
52-
{
53-
fn into_response(self) -> axum::response::Response {
54-
axum::response::IntoResponse::into_response(self.body().map(|bytes| (StatusCode::OK, bytes)))
55-
}
56-
}
57-
58-
/// Implement the [`Response`] for the [`Announce`].
59-
///
60-
impl<E: From<AnnounceData> + Into<Vec<u8>>> Response for Announce<E> {
61-
fn body(self) -> Result<Vec<u8>, responses::error::Error> {
62-
Ok(self.data.into())
63-
}
64-
}
65-
6644
/// Format of the [`Normal`] (Non-Compact) Encoding
6745
pub struct Normal {
6846
complete: i64,
@@ -152,9 +130,9 @@ impl Into<Vec<u8>> for Compact {
152130

153131
/// A [`NormalPeer`], for the [`Normal`] form.
154132
///
155-
/// ```text
133+
/// ```rust
156134
/// use std::net::{IpAddr, Ipv4Addr};
157-
/// use torrust_tracker_lib::servers::http::v1::responses::announce::{Normal, NormalPeer};
135+
/// use bittorrent_http_protocol::v1::responses::announce::{Normal, NormalPeer};
158136
///
159137
/// let peer = NormalPeer {
160138
/// peer_id: *b"-qB00000000000000001",
@@ -204,9 +182,9 @@ impl From<&NormalPeer> for BencodeMut<'_> {
204182
/// A part from reducing the size of the response, this format does not contain
205183
/// the peer's ID.
206184
///
207-
/// ```text
185+
/// ```rust
208186
/// use std::net::{IpAddr, Ipv4Addr};
209-
/// use torrust_tracker_lib::servers::http::v1::responses::announce::{Compact, CompactPeer, CompactPeerData};
187+
/// use bittorrent_http_protocol::v1::responses::announce::{Compact, CompactPeer, CompactPeerData};
210188
///
211189
/// let peer = CompactPeer::V4(CompactPeerData {
212190
/// ip: Ipv4Addr::new(0x69, 0x69, 0x69, 0x69), // 105.105.105.105
@@ -302,11 +280,11 @@ mod tests {
302280

303281
use aquatic_udp_protocol::PeerId;
304282
use torrust_tracker_configuration::AnnouncePolicy;
283+
use torrust_tracker_primitives::core::AnnounceData;
305284
use torrust_tracker_primitives::peer::fixture::PeerBuilder;
306285
use torrust_tracker_primitives::swarm_metadata::SwarmMetadata;
307286

308-
use crate::core::AnnounceData;
309-
use crate::servers::http::v1::responses::announce::{Announce, Compact, Normal, Response};
287+
use crate::v1::responses::announce::{Announce, Compact, Normal};
310288

311289
// Some ascii values used in tests:
312290
//
@@ -345,7 +323,7 @@ mod tests {
345323
#[test]
346324
fn non_compact_announce_response_can_be_bencoded() {
347325
let response: Announce<Normal> = setup_announce_data().into();
348-
let bytes = response.body().expect("it should encode the response");
326+
let bytes = response.data.into();
349327

350328
// cspell:disable-next-line
351329
let expected_bytes = b"d8:completei333e10:incompletei444e8:intervali111e12:min intervali222e5:peersld2:ip15:105.105.105.1057:peer id20:-qB000000000000000014:porti28784eed2:ip39:6969:6969:6969:6969:6969:6969:6969:69697:peer id20:-qB000000000000000024:porti28784eeee";
@@ -359,7 +337,7 @@ mod tests {
359337
#[test]
360338
fn compact_announce_response_can_be_bencoded() {
361339
let response: Announce<Compact> = setup_announce_data().into();
362-
let bytes = response.body().expect("it should encode the response");
340+
let bytes = response.data.into();
363341

364342
let expected_bytes =
365343
// cspell:disable-next-line

src/servers/http/v1/responses/error.rs packages/http-protocol/src/v1/responses/error.rs

+9-7
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@
1111
//! > **NOTICE**: error responses are bencoded and always have a `200 OK` status
1212
//! > code. The official `BitTorrent` specification does not specify the status
1313
//! > code.
14-
use axum::http::StatusCode;
15-
use axum::response::{IntoResponse, Response};
1614
use serde::Serialize;
1715

16+
use crate::v1::services::peer_ip_resolver::PeerIpResolutionError;
17+
1818
/// `Error` response for the [`HTTP tracker`](crate::servers::http).
1919
#[derive(Serialize, Debug, PartialEq)]
2020
pub struct Error {
@@ -26,8 +26,8 @@ pub struct Error {
2626
impl Error {
2727
/// Returns the bencoded representation of the `Error` struct.
2828
///
29-
/// ```text
30-
/// use torrust_tracker_lib::servers::http::v1::responses::error::Error;
29+
/// ```rust
30+
/// use bittorrent_http_protocol::v1::responses::error::Error;
3131
///
3232
/// let err = Error {
3333
/// failure_reason: "error message".to_owned(),
@@ -47,9 +47,11 @@ impl Error {
4747
}
4848
}
4949

50-
impl IntoResponse for Error {
51-
fn into_response(self) -> Response {
52-
(StatusCode::OK, self.write()).into_response()
50+
impl From<PeerIpResolutionError> for Error {
51+
fn from(err: PeerIpResolutionError) -> Self {
52+
Self {
53+
failure_reason: format!("Error resolving peer IP: {err}"),
54+
}
5355
}
5456
}
5557

0 commit comments

Comments
 (0)