actix_web_lab/
host.rs

1use std::convert::Infallible;
2
3use actix_utils::future::{Ready, ok};
4use actix_web::{FromRequest, HttpRequest, dev::Payload};
5
6/// Host information.
7///
8/// See [`ConnectionInfo::host()`](actix_web::dev::ConnectionInfo::host) for more.
9#[derive(Debug, Clone, PartialEq, Eq)]
10pub struct Host(String);
11
12impl_more::impl_as_ref!(Host => String);
13impl_more::impl_into!(Host => String);
14impl_more::forward_display!(Host);
15
16impl Host {
17    /// Unwraps into inner string value.
18    pub fn into_inner(self) -> String {
19        self.0
20    }
21}
22
23impl FromRequest for Host {
24    type Error = Infallible;
25    type Future = Ready<Result<Self, Self::Error>>;
26
27    #[inline]
28    fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
29        ok(Host(req.connection_info().host().to_owned()))
30    }
31}
32
33#[cfg(test)]
34mod tests {
35    use actix_web::{
36        App, HttpResponse,
37        http::StatusCode,
38        test::{self, TestRequest},
39        web,
40    };
41
42    use super::*;
43
44    #[actix_web::test]
45    async fn extracts_host() {
46        let app =
47            test::init_service(App::new().default_service(web::to(|host: Host| async move {
48                HttpResponse::Ok().body(host.to_string())
49            })))
50            .await;
51
52        let req = TestRequest::default()
53            .insert_header(("host", "in-header.com"))
54            .to_request();
55        let res = test::call_service(&app, req).await;
56        assert_eq!(res.status(), StatusCode::OK);
57        assert_eq!(test::read_body(res).await, b"in-header.com".as_ref());
58
59        let req = TestRequest::default().uri("http://in-url.com").to_request();
60        let res = test::call_service(&app, req).await;
61        assert_eq!(res.status(), StatusCode::OK);
62        assert_eq!(test::read_body(res).await, b"in-url.com".as_ref());
63
64        let req = TestRequest::default().to_request();
65        let res = test::call_service(&app, req).await;
66        assert_eq!(res.status(), StatusCode::OK);
67        assert_eq!(test::read_body(res).await, b"localhost:8080".as_ref());
68    }
69}