Struct under::RemoteAddress

source ·
pub struct RemoteAddress<'r> { /* private fields */ }
Expand description

A type that helps retrieve the remote address of a request.

Because the process is incredibly complex, we can’t just have a single function that returns a single IP address - the source of that IP address is incredibly important, and we need to know what sources the application in question trusts.

The basic idea is this: there are multiple potential sources to load an IP address from. All of these potential sources must be derivable from the request itself. The application must then specify which sources it trusts to be able to load an IP address from. Those sources themselves can have their own configurations that allow them to be more fine-grained. We do not suggest a default - or, rather, disencourage it. Instead, we make it easier to specify.

For more information, see https://adam-p.ca/blog/2022/03/x-forwarded-for/.

Examples

request.set_header("X-Forwarded-For", "1.1.1.1, 2.2.2.2, 3.3.3.3");
let ip = request.remote_address()
    .trust_cloudflare_header()
    .trust_forwarded_for(-1)
    .trust_peer_address()
    .apply();
assert_eq!(ip, Some(IpAddr::from([3, 3, 3, 3])));

Implementations§

source§

impl RemoteAddress<'_>

source

pub fn trust_forwarded_for(&mut self, index: isize) -> &mut Self

Adds a source that loads from the X-Forwarded-For header. The index here specifies which entry in the X-Forwarded-For header to use. This is useful for load balancing applications that use multiple load balancers, or have multiple proxies between the application or the user. Ideally, the application would specify the right-most specific source, not including the load balancers.

This source correctly parses multiple X-Forwarded-For headers, implicitly concatenating them.

Examples
request.set_header("X-Forwarded-For", "1.1.1.1, 2.2.2.2, 3.3.3.3");
let ip = request.remote_address()
    .trust_forwarded_for(0)
    .apply();
assert_eq!(ip, Some(IpAddr::from([1, 1, 1, 1])));
let ip = request.remote_address()
    .trust_forwarded_for(-1)
    .apply();
assert_eq!(ip, Some(IpAddr::from([3, 3, 3, 3])));
source

pub fn trust_forwarded(&mut self, index: isize) -> &mut Self

Adds a source that loads from the Forwarded header. The index here specifies which entry in the Forwarded header to use. This is useful for load balancing applications that use multiple load balancers, or have multiple proxies between the application or the user. Ideally, the application would specify the right-most specific source, not including the load balancers.

This source correctly parses multiple Forwarded headers, implicitly concatenating them.

Examples
request.set_header("Forwarded", "for=1.1.1.1, for=2.2.2.2, for=3.3.3.3");
let ip = request.remote_address()
   .trust_forwarded(0)
   .apply();
assert_eq!(ip, Some(IpAddr::from([1, 1, 1, 1])));
let ip = request.remote_address()
  .trust_forwarded(-1)
  .apply();
assert_eq!(ip, Some(IpAddr::from([3, 3, 3, 3])));
source

pub fn trust_header(&mut self, header: impl Into<Cow<'static, str>>) -> &mut Self

Adds a source that loads from a specific header. This is useful for load balancing applications where the load balancer adds a header to the request that contains the IP address of the client. Note that, however, if the load balancer is not trusted, or that the application can ever be accessed without the load balancer, this will not work. This source iterates over all possible header values, from top to bottom, and returns the first one that parses as an IP address.

Examples
request.set_header("X-Real-IP", "1.1.1.1");
request.add_header("X-Real-IP", "2.2.2.2");
let ip = request.remote_address().trust_header("X-Real-IP").apply();
assert_eq!(ip, Some(IpAddr::from([1, 1, 1, 1])));
source

pub fn trust_cloudflare_header(&mut self) -> &mut Self

Adds a source that loads from the header "CF-Connecting-IP". This uses the same logic as Self::trust_header to parse the header.

source

pub fn trust_real_ip_header(&mut self) -> &mut Self

Adds a source that loads from the header "X-Real-IP". This uses the same logic as Self::trust_header to parse the header.

source

pub fn trust_client_ip_header(&mut self) -> &mut Self

Adds a source that loads from the header "True-Client-IP". This uses the same logic as Self::trust_header to parse the header.

source

pub fn trust_peer_address(&mut self) -> &mut Self

Adds a source that loads from the peer address of the TCP connection. There generally will always be a peer address, but if the application is behind a reverse proxy, this peer address will be the address of the reverse proxy, instead of the user’s machine. As such, this is most likely not what you want.

Examples
let ip = request.remote_address()
    .trust_peer_address()
    .apply();
assert_eq!(ip, Some(IpAddr::from([127, 0, 0, 1])));
source

pub fn apply(&self) -> Option<IpAddr>

Applies the sources to the request, extracting the IP address. Since all sources are fallible, this will return None if all of the sources fail. All sources are evaluated from the first source added to the last.

Examples
request.set_header("X-Forwarded-For", "1.1.1.1, 2.2.2.2, 3.3.3.3");
let ip = request.remote_address()
    .trust_cloudflare_header()
    .trust_forwarded_for(-1)
    .trust_peer_address()
    .apply();
assert_eq!(ip, Some(IpAddr::from([3, 3, 3, 3])));

Trait Implementations§

source§

impl<'r> Clone for RemoteAddress<'r>

source§

fn clone(&self) -> RemoteAddress<'r>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'r> Debug for RemoteAddress<'r>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'r> !RefUnwindSafe for RemoteAddress<'r>

§

impl<'r> Send for RemoteAddress<'r>

§

impl<'r> Sync for RemoteAddress<'r>

§

impl<'r> Unpin for RemoteAddress<'r>

§

impl<'r> !UnwindSafe for RemoteAddress<'r>

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

const: unstable · source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

const: unstable · source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

const: unstable · source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for Twhere U: From<T>,

const: unstable · source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for Twhere T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
const: unstable · source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
const: unstable · source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere V: MultiLane<T>,

§

fn vzip(self) -> V

source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more