xitca_http/h1/proto/
context.rs1use core::{mem, net::SocketAddr};
2
3use crate::http::{Extensions, header::HeaderMap};
4
5pub struct Context<'a, D, const HEADER_LIMIT: usize> {
7 addr: SocketAddr,
8 state: ContextState,
9 header: Option<HeaderMap>,
11 exts: Extensions,
13 date: &'a D,
14}
15
16struct ContextState(u8);
19
20impl ContextState {
21 const EXPECT: u8 = 0b_0001;
23 const CONNECT: u8 = 0b_0010;
25 const HEAD: u8 = 0b_0100;
27 const CLOSE: u8 = 0b_1000;
29 const HTTP_10: u8 = 0b1_0000;
31
32 const fn new() -> Self {
33 Self(0)
34 }
35
36 fn insert(&mut self, other: u8) {
37 self.0 |= other;
38 }
39
40 fn remove(&mut self, other: u8) {
41 self.0 &= !other;
42 }
43
44 const fn contains(&self, other: u8) -> bool {
45 (self.0 & other) == other
46 }
47}
48
49impl<'a, D, const HEADER_LIMIT: usize> Context<'a, D, HEADER_LIMIT> {
50 #[inline]
54 pub fn new(date: &'a D) -> Self {
55 Self::with_addr(crate::unspecified_socket_addr(), date)
56 }
57
58 #[inline]
62 pub fn with_addr(addr: SocketAddr, date: &'a D) -> Self {
63 Self {
64 addr,
65 state: ContextState::new(),
66 header: None,
67 exts: Extensions::new(),
68 date,
69 }
70 }
71
72 #[inline]
74 pub fn date(&self) -> &D {
75 self.date
76 }
77
78 #[inline]
82 pub fn take_headers(&mut self) -> HeaderMap {
83 self.header.take().unwrap_or_default()
84 }
85
86 #[inline]
88 pub fn take_extensions(&mut self) -> Extensions {
89 mem::take(&mut self.exts)
90 }
91
92 #[inline]
94 pub fn replace_headers(&mut self, headers: HeaderMap) {
95 debug_assert!(headers.is_empty());
96 self.header = Some(headers);
97 }
98
99 #[inline]
101 pub fn replace_extensions(&mut self, extensions: Extensions) {
102 debug_assert!(extensions.is_empty());
103 self.exts = extensions;
104 }
105
106 #[inline]
108 pub fn reset(&mut self) {
109 self.state = ContextState::new();
110 }
111
112 #[inline]
114 pub fn set_expect_header(&mut self) {
115 self.state.insert(ContextState::EXPECT)
116 }
117
118 #[inline]
120 pub fn set_connect_method(&mut self) {
121 self.state.insert(ContextState::CONNECT)
122 }
123
124 #[inline]
126 pub fn set_head_method(&mut self) {
127 self.state.insert(ContextState::HEAD)
128 }
129
130 #[inline]
132 pub fn set_http10(&mut self) {
133 self.state.insert(ContextState::HTTP_10)
134 }
135
136 #[inline]
138 pub fn set_close(&mut self) {
139 self.state.insert(ContextState::CLOSE)
140 }
141
142 #[inline]
144 pub fn remove_close(&mut self) {
145 self.state.remove(ContextState::CLOSE)
146 }
147
148 #[inline]
150 pub const fn is_expect_header(&self) -> bool {
151 self.state.contains(ContextState::EXPECT)
152 }
153
154 #[inline]
156 pub const fn is_connect_method(&self) -> bool {
157 self.state.contains(ContextState::CONNECT)
158 }
159
160 #[inline]
162 pub const fn is_head_method(&self) -> bool {
163 self.state.contains(ContextState::HEAD)
164 }
165
166 #[inline]
168 pub const fn is_http10(&self) -> bool {
169 self.state.contains(ContextState::HTTP_10)
170 }
171
172 #[inline]
174 pub const fn is_connection_closed(&self) -> bool {
175 self.state.contains(ContextState::CLOSE)
176 }
177
178 #[inline]
180 pub fn socket_addr(&self) -> &SocketAddr {
181 &self.addr
182 }
183}