1use crate::{
2 error::Result,
3 helpers::{
4 self, BufReadExt, SliceU8Ext,
5 MatchConfig::{ Required, Trim }
6 }
7};
8use std::{
9 collections::BTreeMap, iter::FromIterator, ops::Deref,
10 io::{ BufRead, Write }
11};
12
13
14#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
16pub struct Header {
17 start_line: HeaderStartLine,
19 fields: HeaderFields
21}
22impl Header {
23 pub const fn new(start_line: HeaderStartLine, fields: HeaderFields) -> Self {
25 Self { start_line, fields }
26 }
27
28 pub fn start_line(&self) -> &HeaderStartLine {
30 &self.start_line
31 }
32 pub fn start_line_mut(&mut self) -> &mut HeaderStartLine {
34 &mut self.start_line
35 }
36
37 pub fn fields(&self) -> &HeaderFields {
39 &self.fields
40 }
41 pub fn fields_mut(&mut self) -> &mut HeaderFields {
43 &mut self.fields
44 }
45
46 pub fn read<T>(source: &mut T) -> Result<Self> where T: BufRead {
53 let header = source.read_word("\r\n\r\n", [Required])?;
55 let mut header = helpers::memreader(header);
56
57 let start_line = HeaderStartLine::read(&mut header)?;
59 let fields = HeaderFields::read(&mut header)?;
60 Ok(Self { start_line, fields })
61 }
62 pub fn write_all(&self, output: &mut dyn Write) -> Result {
64 self.start_line.write_all(output)?;
65 self.fields.write_all(output)?;
66 output.flush()?;
67 Ok(())
68 }
69}
70
71
72#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
74pub struct HeaderStartLine {
75 field0: Vec<u8>,
76 field1: Vec<u8>,
77 field2: Vec<u8>,
78}
79impl HeaderStartLine {
80 pub fn new_request<T, U>(method: T, target: U) -> Self where T: Into<Vec<u8>>, U: Into<Vec<u8>> {
82 Self {
83 field0: method.into(),
84 field1: target.into(),
85 field2: "HTTP/1.1".into()
86 }
87 }
88 pub fn new_response<T>(status: u16, reason: T) -> Self where T: Into<Vec<u8>> {
90 Self {
91 field0: "HTTP/1.1".into(),
92 field1: status.to_string().into(),
93 field2: reason.into()
94 }
95 }
96
97 pub fn request_method(&self) -> &[u8] {
99 &self.field0
100 }
101 pub fn request_method_mut(&mut self) -> &mut Vec<u8> {
103 &mut self.field0
104 }
105 pub fn request_target(&self) -> &[u8] {
107 &self.field1
108 }
109 pub fn request_target_mut(&mut self) -> &mut Vec<u8> {
111 &mut self.field1
112 }
113
114 pub fn response_binstatus(&self) -> &[u8] {
116 &self.field1
117 }
118 pub fn response_binstatus_mut(&mut self) -> &mut Vec<u8> {
120 &mut self.field1
121 }
122 pub fn response_reason(&self) -> &[u8] {
124 &self.field2
125 }
126 pub fn response_reason_mut(&mut self) -> &mut Vec<u8> {
127 &mut self.field2
128 }
129
130 pub fn read<T>(source: &mut T) -> Result<Self> where T: BufRead {
132 let line = source.read_word("\r\n", [Required, Trim])?;
134 let mut line = helpers::memreader(line);
135 let this = Self {
136 field0: line.read_word(" ", [Required, Trim])?,
137 field1: line.read_word(" ", [Required, Trim])?,
138 field2: line.read_all([Required])?
139 };
140 Ok(this)
141 }
142 pub fn write_all(&self, output: &mut dyn Write) -> Result {
144 output.write_all(&self.field0)?;
145 output.write_all(b" ")?;
146 output.write_all(&self.field1)?;
147 output.write_all(b" ")?;
148 output.write_all(&self.field2)?;
149 output.write_all(b"\r\n")?;
150 Ok(())
151 }
152}
153
154
155#[derive(Debug, Default, Clone, Eq, PartialEq, Ord, PartialOrd)]
157pub struct HeaderFields {
158 fields: BTreeMap<Vec<u8>, Vec<u8>>
160}
161impl HeaderFields {
162 pub fn new() -> Self {
164 Self { fields: BTreeMap::new() }
165 }
166
167 pub fn get<T>(&self, name: T) -> Option<&[u8]> where T: AsRef<[u8]> {
169 let name = name.as_ascii_lowercase();
170 self.fields.get(name.as_ref()).map(|s| s.as_ref())
171 }
172 pub fn set<A, B>(&mut self, name: A, value: B) where A: AsRef<[u8]>, B: Into<Vec<u8>> {
174 let name = name.as_ascii_lowercase();
175 self.fields.insert(name.into(), value.into());
176 }
177
178 pub fn read<T>(source: &mut T) -> Result<Self> where T: BufRead {
180 let mut this = HeaderFields::new();
181 'read_lines: loop {
182 let mut line = match source.read_word("\r\n", [Required, Trim])? {
184 line if line.is_empty() => break 'read_lines,
185 line => helpers::memreader(line)
186 };
187 let key = line.read_word(":", [Required, Trim])?;
188 let value = line.read_all([Required])?;
189
190 let leading_whitespace = value.iter().take_while(|b| **b == b' ').count();
192 let value = &value[leading_whitespace..];
193 this.set(key, value);
194 }
195
196 Ok(this)
197 }
198 pub fn write_all(&self, output: &mut dyn Write) -> Result {
200 for (key, value) in self.fields.iter() {
201 output.write_all(key)?;
202 output.write_all(b": ")?;
203 output.write_all(value)?;
204 output.write_all(b"\r\n")?;
205 }
206 output.write_all(b"\r\n")?;
207 Ok(())
208 }
209}
210impl Deref for HeaderFields {
211 type Target = BTreeMap<Vec<u8>, Vec<u8>>;
212
213 fn deref(&self) -> &Self::Target {
214 &self.fields
215 }
216}
217impl<K, V> FromIterator<(K, V)> for HeaderFields where K: Into<Vec<u8>>, V: Into<Vec<u8>> {
218 fn from_iter<T: IntoIterator<Item = (K, V)>>(pairs: T) -> Self {
219 let fields = pairs.into_iter()
220 .map(|(k, v)| (k.into(), v.into()))
221 .map(|(k, v)| (k.to_ascii_lowercase(), v))
222 .collect();
223 Self { fields }
224 }
225}
226impl IntoIterator for HeaderFields {
227 type Item = <BTreeMap<Vec<u8>, Vec<u8>> as IntoIterator>::Item;
228 type IntoIter = <BTreeMap<Vec<u8>, Vec<u8>> as IntoIterator>::IntoIter;
229
230 fn into_iter(self) -> Self::IntoIter {
231 self.fields.into_iter()
232 }
233}