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