http_protocol/header/
mod.rs1mod utils;
2
3use bytes::Bytes;
4use bytes::{BufMut, BytesMut};
5use std::collections::BTreeMap;
6use std::error::Error;
7use std::fmt;
8use std::ops::Add;
9pub use utils::check_header_value;
10pub use utils::get_header;
11pub use utils::HeaderChar;
12
13#[derive(Debug, Clone)]
14pub enum HeaderError {
15 InvalidHeader,
16 InvalidHeaderValue,
17}
18
19impl fmt::Display for HeaderError {
20 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
21 match self {
22 HeaderError::InvalidHeader => write!(f, "Invalid header."),
23 HeaderError::InvalidHeaderValue => write!(f, "Invalid header value."),
24 }
25 }
26}
27
28impl Error for HeaderError {}
29
30#[derive(Debug, PartialEq, Clone, Ord, Eq, PartialOrd)]
31pub enum Header {
32 Host,
33 Connection,
34 CacheControl,
35 UpgradeInsecureRequests,
36 UserAgent,
37 Accept,
38 SecFetchSite,
39 SecFetchMode,
40 SecFetchDest,
41 SecFetchUser,
42 AcceptEncoding,
43 AcceptLanguage,
44 Authorization,
45 ContentEncoding,
46 ContentLength,
47 ContentType,
48 Upgrade,
49 Pragma,
50 Referer,
51}
52
53impl From<Header> for Bytes {
54 fn from(h: Header) -> Self {
55 match h {
56 Header::Host => Bytes::from_static(b"Host"),
57 Header::Connection => Bytes::from_static(b"Connection"),
58 Header::CacheControl => Bytes::from_static(b"Cache-Control"),
59 Header::UpgradeInsecureRequests => Bytes::from_static(b"Upgrade-Insecure-Requests"),
60 Header::UserAgent => Bytes::from_static(b"User-Agent"),
61 Header::Accept => Bytes::from_static(b"Accept"),
62 Header::SecFetchSite => Bytes::from_static(b"Sec-Fetch-Site"),
63 Header::SecFetchMode => Bytes::from_static(b"Sec-Fetch-Mode"),
64 Header::SecFetchDest => Bytes::from_static(b"Sec-Fetch-Dest"),
65 Header::SecFetchUser => Bytes::from_static(b"Sec-Fetch-User"),
66 Header::AcceptEncoding => Bytes::from_static(b"Accept-Encoding"),
67 Header::AcceptLanguage => Bytes::from_static(b"Accept-Language"),
68 Header::Authorization => Bytes::from_static(b"Authorization"),
69 Header::ContentEncoding => Bytes::from_static(b"Content-Encoding"),
70 Header::ContentLength => Bytes::from_static(b"Content-Length"),
71 Header::ContentType => Bytes::from_static(b"Content-Type"),
72 Header::Upgrade => Bytes::from_static(b"Upgrade"),
73 Header::Pragma => Bytes::from_static(b"Pragma"),
74 Header::Referer => Bytes::from_static(b"Referer"),
75 }
76 }
77}
78
79#[derive(Debug, Clone, Eq, PartialEq)]
80pub struct Headers {
81 inner: BTreeMap<Header, Bytes>,
82}
83
84impl Headers {
85 pub fn new() -> Self {
86 Headers {
87 inner: BTreeMap::new(),
88 }
89 }
90
91 pub fn insert<T>(&mut self, key: Header, value: T)
92 where
93 T: Into<Bytes>,
94 {
95 self.inner.insert(key, value.into());
96 }
97
98 pub fn get(&self, key: Header) -> Option<&Bytes> {
99 self.inner.get(&key)
100 }
101
102 pub fn remove(&mut self, key: Header) {
103 self.inner.remove(&key);
104 }
105
106 pub fn append(&mut self, mut other: Headers) {
107 self.inner.append(&mut other.inner);
108 }
109}
110
111impl Add<Headers> for Headers {
112 type Output = Self;
113
114 fn add(mut self, other: Self) -> Self::Output {
115 self.append(other);
116 self
117 }
118}
119
120impl From<Headers> for Bytes {
121 fn from(x: Headers) -> Self {
122 let mut buf = BytesMut::new();
123 for (h, b) in x.inner {
124 buf.put(Bytes::from(h));
125 buf.put(Bytes::from_static(&[58u8, sp!()]));
126 buf.put(b);
127 buf.put(Bytes::from_static(&[cr!(), lf!()]));
128 }
129 buf.freeze()
130 }
131}