sark_http/h1/head/request/
mod.rs1pub mod offers;
4mod parts;
5mod plan;
6pub mod pool;
7mod route;
8pub mod scan;
9pub mod trace;
10
11pub use parts::Parts;
12pub(in crate::h1::head::request) use plan::Kind;
13pub use plan::Plan;
14pub use route::Route;
15
16use crate::{
17 field::head::Name,
18 h1::{
19 field::{self, Connection, Transfer, expect},
20 framing,
21 head::{Semantic, line},
22 switch, target,
23 },
24 payload::response::Method,
25 request::{self, span},
26};
27
28#[derive(Clone, Copy, Default)]
29pub struct Fields {
30 pub message: Message,
31 pub routing: Routing,
32}
33
34impl Fields {
35 fn apply(mut self, field: &field::Entry<'_>, version: line::Version) -> Result<Self, Semantic> {
36 let value = field.value();
37 match field.kind() {
38 Name::ContentLength => {
39 self.message.framing = self
40 .message
41 .framing
42 .try_length(value)
43 .map_err(Semantic::Field)?;
44 }
45 Name::TransferEncoding => {
46 self.message = self.message.try_coding(value).map_err(Semantic::Field)?;
47 }
48 Name::Host => {
49 self.routing.authority = self
50 .routing
51 .authority
52 .try_host(value)
53 .map_err(Semantic::Host)?;
54 self.routing.host = Some(field.value_span());
55 }
56 Name::Expect => {
57 self.message = self.message.with_expect(value);
58 }
59 Name::Connection => {
60 self.routing.connection = self
61 .routing
62 .connection
63 .try_push(value)
64 .map_err(Semantic::Connection)?;
65 }
66 Name::Upgrade => {
67 self.routing = self
68 .routing
69 .try_upgrade(value, version)
70 .map_err(Semantic::Upgrade)?;
71 }
72 Name::Invalid
73 | Name::Method
74 | Name::Scheme
75 | Name::Path
76 | Name::Status
77 | Name::Authority
78 | Name::Protocol
79 | Name::AcceptEncoding
80 | Name::Te
81 | Name::KeepAlive
82 | Name::ProxyConnection
83 | Name::Regular => {}
84 }
85 Ok(self)
86 }
87
88 pub fn admit_target(
89 self,
90 target: target::Target,
91 version: &[u8],
92 policy: target::Policy,
93 ) -> Result<framing::Admission, Semantic> {
94 framing::Admission::admit(
95 self.message.framing,
96 self.routing.authority,
97 self.message.expectation,
98 target,
99 version,
100 policy,
101 )
102 .map_err(Semantic::Admission)
103 }
104
105 pub fn transition(
106 self,
107 method: Method,
108 version: line::Version,
109 ) -> Result<switch::Intent, Semantic> {
110 switch::Intent::from_request(
111 method,
112 self.routing.connection,
113 self.routing.upgrades,
114 version,
115 )
116 .map_err(Semantic::Transition)
117 }
118
119 pub(super) fn admit_parts(
120 self,
121 target: target::Target,
122 range: span::Span,
123 version: line::Version,
124 ) -> Result<(framing::Admission, request::Layout, span::Span), Semantic> {
125 let admit = self.admit_target(target, version.as_bytes(), target::Policy::Require)?;
126 let auth = admit
127 .authority()
128 .span(target, self.routing.host)
129 .map_err(Semantic::Authority)?;
130 let request = target.layout(range, auth).map_err(Semantic::Authority)?;
131 Ok((admit, request, auth))
132 }
133
134 pub(super) const fn connection(self) -> Connection {
135 self.routing.connection
136 }
137
138 pub(super) const fn upgrades(self) -> switch::Offers {
139 self.routing.upgrades
140 }
141}
142
143const _: () = assert!(core::mem::size_of::<Fields>() <= 6 * core::mem::size_of::<usize>());
144
145#[derive(Clone, Copy, Default, PartialEq, Eq)]
146#[repr(u8)]
147pub enum Coding {
148 #[default]
149 Plain,
150 Gzip,
151}
152
153const _: () = assert!(core::mem::size_of::<Coding>() == core::mem::size_of::<bool>());
154
155#[derive(Clone, Copy, Default)]
156pub struct Message {
157 framing: framing::Fields,
158 expectation: expect::State,
159 coding: Coding,
160}
161
162impl Message {
163 pub fn try_length(mut self, length: usize) -> Result<Self, field::Error> {
164 self.framing = self.framing.try_set(length)?;
165 Ok(self)
166 }
167
168 pub fn try_coding(mut self, value: &[u8]) -> Result<Self, field::Error> {
169 self.framing = self.framing.try_coding(value)?;
170 Ok(self)
171 }
172
173 pub fn try_append(mut self, value: Transfer) -> Result<Self, field::Error> {
174 self.framing = self.framing.try_append(value)?;
175 Ok(self)
176 }
177
178 pub fn with_expect(mut self, value: &[u8]) -> Self {
179 self.expectation = self.expectation.push(value);
180 self
181 }
182
183 pub const fn length(self) -> Option<usize> {
184 self.framing.length()
185 }
186
187 pub const fn has_coding(self) -> bool {
188 self.framing.has_coding()
189 }
190
191 pub const fn is_chunked(self) -> bool {
192 self.framing.is_chunked()
193 }
194
195 pub const fn has_other_transfer_coding(self) -> bool {
197 self.framing.has_other()
198 }
199
200 pub(crate) fn set_coding(&mut self, coding: Coding) {
201 self.coding = coding;
202 }
203
204 pub const fn coding(self) -> Coding {
205 self.coding
206 }
207}
208
209#[derive(Clone, Copy, Default)]
210pub struct Routing {
211 pub(crate) authority: target::Request,
212 pub(crate) connection: Connection,
213 pub(in crate::h1::head::request) host: Option<span::Span>,
214 pub(in crate::h1::head::request) upgrades: switch::Offers,
215}
216
217impl Routing {
218 pub const fn connection(self) -> Connection {
219 self.connection
220 }
221
222 pub fn try_host(mut self, span: span::Span) -> Result<Self, target::Invalid> {
223 if !self.authority.has_host() || self.host.is_some() {
224 return Err(target::Invalid);
225 }
226 self.host = Some(span);
227 Ok(self)
228 }
229
230 pub const fn host_span(self) -> Option<span::Span> {
231 self.host
232 }
233
234 pub fn try_upgrade(
235 mut self,
236 value: &[u8],
237 version: line::Version,
238 ) -> Result<Self, switch::UpgradeError> {
239 if version == line::Version::Ten {
240 return Ok(self);
241 }
242 let next = self.upgrades.try_push(value)?;
243 self.upgrades = next;
244 Ok(self)
245 }
246}