gotham/state/
client_addr.rs

1//! Defines storage for the remote address of the client
2
3use crate::state::{FromState, State, StateData};
4use std::net::SocketAddr;
5
6struct ClientAddr {
7    addr: SocketAddr,
8}
9
10impl StateData for ClientAddr {}
11
12pub(crate) fn put_client_addr(state: &mut State, addr: SocketAddr) {
13    state.put(ClientAddr { addr })
14}
15
16/// Returns the client `SocketAddr` as reported by hyper, if one was present. Certain connections
17/// do not report a client address, in which case this will return `None`.
18///
19/// # Examples
20///
21/// ```rust
22/// # extern crate gotham;
23/// # extern crate hyper;
24/// # extern crate mime;
25/// #
26/// # use hyper::{Body, Response, StatusCode};
27/// # use gotham::helpers::http::response::create_response;
28/// # use gotham::state::{State, client_addr};
29/// # use gotham::test::TestServer;
30/// #
31/// fn my_handler(state: State) -> (State, Response<Body>) {
32///     let addr = client_addr(&state).expect("no client address");
33///
34///     let body = format!("{}", addr);
35///     let response = create_response(
36///         &state,
37///         StatusCode::OK,
38///         mime::TEXT_PLAIN,
39///         body,
40///     );
41///
42///     (state, response)
43/// }
44/// #
45/// # fn main() {
46/// #   let test_server = TestServer::new(|| Ok(my_handler)).unwrap();
47/// #   let response = test_server
48/// #       .client()
49/// #       .get("http://localhost/")
50/// #       .perform()
51/// #       .unwrap();
52/// #
53/// #   assert_eq!(response.status(), StatusCode::OK);
54/// #
55/// #   let buf = response.read_body().unwrap();
56/// #   // at the moment, can't actually force the client address
57/// #   assert!(buf.starts_with(b"127.0.0.1"));
58/// # }
59pub fn client_addr(state: &State) -> Option<SocketAddr> {
60    ClientAddr::try_borrow_from(state).map(|c| c.addr)
61}