headers/common/
host.rs

1use std::convert::TryFrom;
2use std::fmt;
3
4use http::uri::Authority;
5use http::{HeaderName, HeaderValue};
6
7use crate::{Error, Header};
8
9/// The `Host` header.
10#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd)]
11pub struct Host(Authority);
12
13impl Host {
14    /// Get the hostname, such as example.domain.
15    pub fn hostname(&self) -> &str {
16        self.0.host()
17    }
18
19    /// Get the optional port number.
20    pub fn port(&self) -> Option<u16> {
21        self.0.port_u16()
22    }
23}
24
25impl Header for Host {
26    fn name() -> &'static HeaderName {
27        &::http::header::HOST
28    }
29
30    fn decode<'i, I: Iterator<Item = &'i HeaderValue>>(values: &mut I) -> Result<Self, Error> {
31        values
32            .next()
33            .cloned()
34            .and_then(|val| Authority::try_from(val.as_bytes()).ok())
35            .map(Host)
36            .ok_or_else(Error::invalid)
37    }
38
39    fn encode<E: Extend<HeaderValue>>(&self, values: &mut E) {
40        let bytes = self.0.as_str().as_bytes();
41        let val = HeaderValue::from_bytes(bytes).expect("Authority is a valid HeaderValue");
42
43        values.extend(::std::iter::once(val));
44    }
45}
46
47impl From<Authority> for Host {
48    fn from(auth: Authority) -> Host {
49        Host(auth)
50    }
51}
52
53impl fmt::Display for Host {
54    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
55        fmt::Display::fmt(&self.0, f)
56    }
57}