rama_http_headers/common/
host.rs1use std::convert::TryFrom;
2use std::fmt;
3
4use rama_core::{bytes::Bytes, telemetry::tracing};
5use rama_http_types::{HeaderName, HeaderValue};
6use rama_net::address::{self, HostWithOptPort};
7
8use crate::{Error, HeaderDecode, HeaderEncode, TypedHeader};
9
10#[derive(Clone, Debug, PartialEq, Eq, Hash)]
12pub struct Host(pub HostWithOptPort);
13
14impl TypedHeader for Host {
15 fn name() -> &'static HeaderName {
16 &::rama_http_types::header::HOST
17 }
18}
19
20impl HeaderDecode for Host {
21 fn decode<'i, I: Iterator<Item = &'i HeaderValue>>(values: &mut I) -> Result<Self, Error> {
22 let addr = values
23 .next()
24 .and_then(|val| HostWithOptPort::try_from(val.as_bytes()).ok())
25 .ok_or_else(Error::invalid)?;
26 Ok(Self(addr))
27 }
28}
29
30impl HeaderEncode for Host {
31 fn encode<E: Extend<HeaderValue>>(&self, values: &mut E) {
32 let s = self.to_string();
33 let bytes = Bytes::from_owner(s);
34
35 match HeaderValue::from_maybe_shared(bytes) {
36 Ok(value) => values.extend(::std::iter::once(value)),
37 Err(err) => {
38 tracing::debug!(
39 "failed to encode stringified authority (host w/ opt port) as header value: {err}"
40 );
41 }
42 }
43 }
44}
45
46impl From<address::Host> for Host {
47 #[inline(always)]
48 fn from(host: address::Host) -> Self {
49 Self(host.into())
50 }
51}
52
53impl From<Host> for address::Host {
54 #[inline(always)]
55 fn from(value: Host) -> Self {
56 value.0.host
57 }
58}
59
60impl From<HostWithOptPort> for Host {
61 #[inline(always)]
62 fn from(addr: HostWithOptPort) -> Self {
63 Self(addr)
64 }
65}
66
67impl From<Host> for HostWithOptPort {
68 #[inline(always)]
69 fn from(host: Host) -> Self {
70 host.0
71 }
72}
73
74impl From<address::HostWithPort> for Host {
75 #[inline(always)]
76 fn from(addr: address::HostWithPort) -> Self {
77 Self(addr.into())
78 }
79}
80
81impl fmt::Display for Host {
82 #[inline(always)]
83 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
84 self.0.fmt(f)
85 }
86}