Skip to content

Commit 2e25d53

Browse files
committed
fix: (HTTP) getting the peer address from x-forwarded-for when it is an array
1 parent 2954380 commit 2e25d53

File tree

1 file changed

+53
-45
lines changed

1 file changed

+53
-45
lines changed

src/torrust_http_tracker/filters.rs

Lines changed: 53 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,50 @@ pub fn with_info_hash() -> impl Filter<Extract = (Vec<InfoHash>,), Error = Rejec
2020
.and_then(info_hashes)
2121
}
2222

23+
/// Check for PeerId
24+
pub fn with_peer_id() -> impl Filter<Extract = (PeerId,), Error = Rejection> + Clone {
25+
warp::filters::query::raw()
26+
.and_then(peer_id)
27+
}
28+
29+
/// Pass Arc<TorrentTracker> along
30+
pub fn with_auth_key() -> impl Filter<Extract = (Option<AuthKey>,), Error = Infallible> + Clone {
31+
warp::path::param::<String>()
32+
.map(|key: String| {
33+
AuthKey::from_string(&key)
34+
})
35+
.or_else(|_| async {
36+
Ok::<(Option<AuthKey>,), Infallible>((None,))
37+
})
38+
}
39+
40+
/// Check for PeerAddress
41+
pub fn with_peer_addr(on_reverse_proxy: bool) -> impl Filter<Extract = (IpAddr,), Error = Rejection> + Clone {
42+
warp::addr::remote()
43+
.and(warp::header::optional::<String>("X-Forwarded-For"))
44+
.map(move |remote_addr: Option<SocketAddr>, x_forwarded_for: Option<String>| {
45+
(on_reverse_proxy, remote_addr, x_forwarded_for)
46+
})
47+
.and_then(peer_addr)
48+
}
49+
50+
/// Check for AnnounceRequest
51+
pub fn with_announce_request(on_reverse_proxy: bool) -> impl Filter<Extract = (AnnounceRequest,), Error = Rejection> + Clone {
52+
warp::filters::query::query::<AnnounceRequestQuery>()
53+
.and(with_info_hash())
54+
.and(with_peer_id())
55+
.and(with_peer_addr(on_reverse_proxy))
56+
.and_then(announce_request)
57+
}
58+
59+
/// Check for ScrapeRequest
60+
pub fn with_scrape_request(on_reverse_proxy: bool) -> impl Filter<Extract = (ScrapeRequest,), Error = Rejection> + Clone {
61+
warp::any()
62+
.and(with_info_hash())
63+
.and(with_peer_addr(on_reverse_proxy))
64+
.and_then(scrape_request)
65+
}
66+
2367
/// Parse InfoHash from raw query string
2468
async fn info_hashes(raw_query: String) -> WebResult<Vec<InfoHash>> {
2569
let split_raw_query: Vec<&str> = raw_query.split("&").collect();
@@ -45,12 +89,6 @@ async fn info_hashes(raw_query: String) -> WebResult<Vec<InfoHash>> {
4589
}
4690
}
4791

48-
/// Check for PeerId
49-
pub fn with_peer_id() -> impl Filter<Extract = (PeerId,), Error = Rejection> + Clone {
50-
warp::filters::query::raw()
51-
.and_then(peer_id)
52-
}
53-
5492
/// Parse PeerId from raw query string
5593
async fn peer_id(raw_query: String) -> WebResult<PeerId> {
5694
// put all query params in a vec
@@ -88,27 +126,6 @@ async fn peer_id(raw_query: String) -> WebResult<PeerId> {
88126
}
89127
}
90128

91-
/// Pass Arc<TorrentTracker> along
92-
pub fn with_auth_key() -> impl Filter<Extract = (Option<AuthKey>,), Error = Infallible> + Clone {
93-
warp::path::param::<String>()
94-
.map(|key: String| {
95-
AuthKey::from_string(&key)
96-
})
97-
.or_else(|_| async {
98-
Ok::<(Option<AuthKey>,), Infallible>((None,))
99-
})
100-
}
101-
102-
/// Check for PeerAddress
103-
pub fn with_peer_addr(on_reverse_proxy: bool) -> impl Filter<Extract = (IpAddr,), Error = Rejection> + Clone {
104-
warp::addr::remote()
105-
.and(warp::header::optional::<String>("X-Forwarded-For"))
106-
.map(move |remote_addr: Option<SocketAddr>, x_forwarded_for: Option<String>| {
107-
(on_reverse_proxy, remote_addr, x_forwarded_for)
108-
})
109-
.and_then(peer_addr)
110-
}
111-
112129
/// Get PeerAddress from RemoteAddress or Forwarded
113130
async fn peer_addr((on_reverse_proxy, remote_addr, x_forwarded_for): (bool, Option<SocketAddr>, Option<String>)) -> WebResult<IpAddr> {
114131
if !on_reverse_proxy && remote_addr.is_none() {
@@ -121,7 +138,15 @@ async fn peer_addr((on_reverse_proxy, remote_addr, x_forwarded_for): (bool, Opti
121138

122139
match on_reverse_proxy {
123140
true => {
124-
IpAddr::from_str(x_forwarded_for.as_ref().unwrap()).or_else(|e| {
141+
let mut x_forwarded_for_raw = x_forwarded_for.unwrap();
142+
// remove whitespace chars
143+
x_forwarded_for_raw.retain(|c| !c.is_whitespace());
144+
// get all forwarded ip's in a vec
145+
let x_forwarded_ips: Vec<&str> = x_forwarded_for_raw.split(',').collect();
146+
// set client ip to last forwarded ip
147+
let x_forwarded_ip = *x_forwarded_ips.last().unwrap();
148+
149+
IpAddr::from_str(x_forwarded_ip).or_else(|e| {
125150
debug!("{}", e);
126151
Err(reject::custom(ServerError::AddressNotFound))
127152
})
@@ -130,15 +155,6 @@ async fn peer_addr((on_reverse_proxy, remote_addr, x_forwarded_for): (bool, Opti
130155
}
131156
}
132157

133-
/// Check for AnnounceRequest
134-
pub fn with_announce_request(on_reverse_proxy: bool) -> impl Filter<Extract = (AnnounceRequest,), Error = Rejection> + Clone {
135-
warp::filters::query::query::<AnnounceRequestQuery>()
136-
.and(with_info_hash())
137-
.and(with_peer_id())
138-
.and(with_peer_addr(on_reverse_proxy))
139-
.and_then(announce_request)
140-
}
141-
142158
/// Parse AnnounceRequest from raw AnnounceRequestQuery, InfoHash and Option<SocketAddr>
143159
async fn announce_request(announce_request_query: AnnounceRequestQuery, info_hashes: Vec<InfoHash>, peer_id: PeerId, peer_addr: IpAddr) -> WebResult<AnnounceRequest> {
144160
Ok(AnnounceRequest {
@@ -154,14 +170,6 @@ async fn announce_request(announce_request_query: AnnounceRequestQuery, info_has
154170
})
155171
}
156172

157-
/// Check for ScrapeRequest
158-
pub fn with_scrape_request(on_reverse_proxy: bool) -> impl Filter<Extract = (ScrapeRequest,), Error = Rejection> + Clone {
159-
warp::any()
160-
.and(with_info_hash())
161-
.and(with_peer_addr(on_reverse_proxy))
162-
.and_then(scrape_request)
163-
}
164-
165173
/// Parse ScrapeRequest from InfoHash
166174
async fn scrape_request(info_hashes: Vec<InfoHash>, peer_addr: IpAddr) -> WebResult<ScrapeRequest> {
167175
Ok(ScrapeRequest {

0 commit comments

Comments
 (0)