|
1 | 1 | use std::convert::Infallible; |
2 | 2 | use std::net::{IpAddr, SocketAddr}; |
3 | 3 | use std::panic::Location; |
4 | | -use std::str::FromStr; |
5 | 4 | use std::sync::Arc; |
6 | 5 |
|
7 | 6 | use warp::{reject, Filter, Rejection}; |
8 | 7 |
|
9 | 8 | use super::error::Error; |
10 | 9 | use super::{request, WebResult}; |
| 10 | +use crate::http::handlers::maybe_rightmost_forwarded_ip; |
11 | 11 | use crate::http::percent_encoding::{percent_decode_info_hash, percent_decode_peer_id}; |
12 | 12 | use crate::protocol::common::MAX_SCRAPE_TORRENTS; |
13 | 13 | use crate::protocol::info_hash::InfoHash; |
@@ -138,41 +138,33 @@ fn peer_id(raw_query: &String) -> WebResult<peer::Id> { |
138 | 138 | } |
139 | 139 | } |
140 | 140 |
|
141 | | -/// Get `PeerAddress` from `RemoteAddress` or Forwarded |
142 | | -fn peer_addr((on_reverse_proxy, remote_addr, x_forwarded_for): (bool, Option<SocketAddr>, Option<String>)) -> WebResult<IpAddr> { |
143 | | - if !on_reverse_proxy && remote_addr.is_none() { |
144 | | - return Err(reject::custom(Error::AddressNotFound { |
145 | | - location: Location::caller(), |
146 | | - message: "neither on have remote address or on a reverse proxy".to_string(), |
147 | | - })); |
148 | | - } |
| 141 | +/// Get peer IP from HTTP client IP or X-Forwarded-For HTTP header |
| 142 | +fn peer_addr( |
| 143 | + (on_reverse_proxy, remote_client_ip, maybe_x_forwarded_for): (bool, Option<SocketAddr>, Option<String>), |
| 144 | +) -> WebResult<IpAddr> { |
| 145 | + if on_reverse_proxy { |
| 146 | + if maybe_x_forwarded_for.is_none() { |
| 147 | + return Err(reject::custom(Error::AddressNotFound { |
| 148 | + location: Location::caller(), |
| 149 | + message: "must have a x-forwarded-for when using a reverse proxy".to_string(), |
| 150 | + })); |
| 151 | + } |
149 | 152 |
|
150 | | - if on_reverse_proxy && x_forwarded_for.is_none() { |
151 | | - return Err(reject::custom(Error::AddressNotFound { |
152 | | - location: Location::caller(), |
153 | | - message: "must have a x-forwarded-for when using a reverse proxy".to_string(), |
154 | | - })); |
155 | | - } |
| 153 | + let x_forwarded_for = maybe_x_forwarded_for.unwrap(); |
156 | 154 |
|
157 | | - if on_reverse_proxy { |
158 | | - let mut x_forwarded_for_raw = x_forwarded_for.unwrap(); |
159 | | - // remove whitespace chars |
160 | | - x_forwarded_for_raw.retain(|c| !c.is_whitespace()); |
161 | | - // get all forwarded ip's in a vec |
162 | | - let x_forwarded_ips: Vec<&str> = x_forwarded_for_raw.split(',').collect(); |
163 | | - // set client ip to last forwarded ip |
164 | | - let x_forwarded_ip = *x_forwarded_ips.last().unwrap(); |
165 | | - |
166 | | - IpAddr::from_str(x_forwarded_ip).map_err(|e| { |
| 155 | + maybe_rightmost_forwarded_ip(&x_forwarded_for).map_err(|e| { |
167 | 156 | reject::custom(Error::AddressNotFound { |
168 | 157 | location: Location::caller(), |
169 | | - message: format!( |
170 | | - "on remote proxy and unable to parse the last x-forwarded-ip: `{e}`, from `{x_forwarded_for_raw}`" |
171 | | - ), |
| 158 | + message: format!("on remote proxy and unable to parse the last x-forwarded-ip: `{e}`, from `{x_forwarded_for}`"), |
172 | 159 | }) |
173 | 160 | }) |
| 161 | + } else if remote_client_ip.is_none() { |
| 162 | + return Err(reject::custom(Error::AddressNotFound { |
| 163 | + location: Location::caller(), |
| 164 | + message: "neither on have remote address or on a reverse proxy".to_string(), |
| 165 | + })); |
174 | 166 | } else { |
175 | | - Ok(remote_addr.unwrap().ip()) |
| 167 | + return Ok(remote_client_ip.unwrap().ip()); |
176 | 168 | } |
177 | 169 | } |
178 | 170 |
|
|
0 commit comments