rama_http_headers/common/
host.rs1use std::convert::TryFrom;
2use std::fmt;
3use std::net::IpAddr;
4
5use bytes::Bytes;
6use rama_http_types::dep::http::uri;
7use rama_http_types::{HeaderName, HeaderValue};
8use rama_net::address;
9
10use crate::{Error, Header};
11
12#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd)]
14pub struct Host {
15 host: address::Host,
16 port: Option<u16>,
17}
18
19impl Host {
20 pub fn host(&self) -> &address::Host {
22 &self.host
23 }
24
25 pub fn port(&self) -> Option<u16> {
27 self.port
28 }
29
30 pub fn into_parts(self) -> (address::Host, Option<u16>) {
32 (self.host, self.port)
33 }
34}
35
36impl Header for Host {
37 fn name() -> &'static HeaderName {
38 &::rama_http_types::header::HOST
39 }
40
41 fn decode<'i, I: Iterator<Item = &'i HeaderValue>>(values: &mut I) -> Result<Self, Error> {
42 let auth = values
43 .next()
44 .and_then(|val| uri::Authority::try_from(val.as_bytes()).ok())
45 .ok_or_else(Error::invalid)?;
46 let host = address::Host::try_from(auth.host()).map_err(|_| Error::invalid())?;
47 let port = auth.port_u16();
48 Ok(Self { host, port })
49 }
50
51 fn encode<E: Extend<HeaderValue>>(&self, values: &mut E) {
52 let s = self.to_string();
53 let bytes = Bytes::from_owner(s);
54 let val = HeaderValue::from_maybe_shared(bytes).expect("Authority is a valid HeaderValue");
55
56 values.extend(::std::iter::once(val));
57 }
58}
59
60impl From<address::Host> for Host {
61 fn from(host: address::Host) -> Host {
62 Host { host, port: None }
63 }
64}
65
66impl From<address::Authority> for Host {
67 fn from(auth: address::Authority) -> Host {
68 let (host, port) = auth.into_parts();
69 Host {
70 host,
71 port: Some(port),
72 }
73 }
74}
75
76impl fmt::Display for Host {
77 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
78 match self.port {
79 Some(port) => match &self.host {
80 address::Host::Address(IpAddr::V6(ip)) => write!(f, "[{ip}]:{port}"),
81 host => write!(f, "{host}:{port}"),
82 },
83 None => self.host.fmt(f),
84 }
85 }
86}