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