Skip to main content

actix_web_lab/
host.rs

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