Skip to main content

sark_http/field/head/
mod.rs

1pub 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;