sark_http/field/head/
mod.rs1pub mod headers;
2pub(super) mod known;
3mod parse;
4
5use core::mem;
6
7use known::Known;
8
9pub use parse::AcceptEncoding;
10
11use crate::{
12 field::text::IntError,
13 h1::{
14 field::{self, TokenError, value},
15 switch, target,
16 },
17};
18
19#[derive(Clone, Copy, PartialEq, Eq, Debug)]
20pub enum Error {
21 Value,
22 Connection(TokenError),
23 ContentLength(IntError),
24 TransferEncoding(value::Error),
25 Host(target::HostError),
26 Message(field::Error),
27 Routing(target::Invalid),
28 Upgrade(switch::UpgradeError),
29}
30
31const _: () = {
32 assert!(mem::size_of::<Error>() == 3 * mem::size_of::<usize>());
33 assert!(mem::size_of::<Option<Error>>() == mem::size_of::<Error>());
34 assert!(!mem::needs_drop::<Error>());
35};
36
37#[derive(Clone, Copy, Default, PartialEq, Eq)]
38pub struct Flags(u16);
39
40impl Flags {
41 pub fn is_set(self, bit: u16) -> bool {
42 (self.0 & bit) != 0
43 }
44
45 pub fn set(&mut self, bit: u16) {
46 self.0 |= bit;
47 }
48}
49
50#[repr(u8)]
51#[derive(Clone, Copy, PartialEq, Eq, Debug)]
52pub enum Name {
53 Invalid,
54 Method,
55 Scheme,
56 Path,
57 Status,
58 Authority,
59 Protocol,
60 Host,
61 Connection,
62 ContentLength,
63 TransferEncoding,
64 Expect,
65 AcceptEncoding,
66 Te,
67 KeepAlive,
68 ProxyConnection,
69 Upgrade,
70 Regular,
71}
72
73impl Name {
74 pub const H1: [Self; 7] = [
75 Self::Host,
76 Self::Connection,
77 Self::ContentLength,
78 Self::TransferEncoding,
79 Self::Expect,
80 Self::AcceptEncoding,
81 Self::Upgrade,
82 ];
83
84 pub const fn wire(&self) -> &[u8] {
85 match self {
86 Self::Method => b":method",
87 Self::Scheme => b":scheme",
88 Self::Path => b":path",
89 Self::Status => b":status",
90 Self::Authority => b":authority",
91 Self::Protocol => b":protocol",
92 Self::Host => Known::Host.as_str().as_bytes(),
93 Self::Connection => Known::Connection.as_str().as_bytes(),
94 Self::ContentLength => Known::ContentLength.as_str().as_bytes(),
95 Self::TransferEncoding => Known::TransferEncoding.as_str().as_bytes(),
96 Self::Expect => Known::Expect.as_str().as_bytes(),
97 Self::AcceptEncoding => Known::AcceptEncoding.as_str().as_bytes(),
98 Self::Te => Known::Te.as_str().as_bytes(),
99 Self::KeepAlive => Known::KeepAlive.as_str().as_bytes(),
100 Self::ProxyConnection => Known::ProxyConnection.as_str().as_bytes(),
101 Self::Upgrade => Known::Upgrade.as_str().as_bytes(),
102 Self::Invalid | Self::Regular => b"",
103 }
104 }
105
106 pub const fn is_required(self) -> bool {
107 matches!(
108 self,
109 Self::Host
110 | Self::Connection
111 | Self::ContentLength
112 | Self::TransferEncoding
113 | Self::Expect
114 | Self::Upgrade
115 )
116 }
117
118 pub fn from_h1(name: &[u8]) -> Option<Self> {
119 let known = match name.len() {
120 4 => Self::Host,
121 6 => Self::Expect,
122 7 => Self::Upgrade,
123 10 if name.first()?.eq_ignore_ascii_case(&b'k') => Self::KeepAlive,
124 10 => Self::Connection,
125 14 => Self::ContentLength,
126 15 => Self::AcceptEncoding,
127 17 => Self::TransferEncoding,
128 _ => return None,
129 };
130 name.eq_ignore_ascii_case(known.wire()).then_some(known)
131 }
132}
133
134pub const MAX_HEADER_LINE_BYTES: usize = 8 * 1024;