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