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}