Skip to main content

leyline/profile/
anchor.rs

1#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
2#[non_exhaustive]
3pub enum HeaderAnchor {
4    BeforeCchUa,
5    AfterCchUa,
6    AfterCchUaMobile,
7    AfterCchUaPlatform,
8    AfterUserAgent,
9    AfterAccept,
10    AfterContentType,
11    AfterFetchDest,
12    BeforeAcceptEncoding,
13}
14
15impl HeaderAnchor {
16    pub(crate) fn anchor_name(&self) -> &'static str {
17        match self {
18            Self::BeforeCchUa | Self::AfterCchUa => "sec-ch-ua",
19            Self::AfterCchUaMobile => "sec-ch-ua-mobile",
20            Self::AfterCchUaPlatform => "sec-ch-ua-platform",
21            Self::AfterUserAgent => "user-agent",
22            Self::AfterAccept => "accept",
23            Self::AfterContentType => "content-type",
24            Self::AfterFetchDest => "sec-fetch-dest",
25            Self::BeforeAcceptEncoding => "accept-encoding",
26        }
27    }
28
29    pub(crate) fn is_before(&self) -> bool {
30        matches!(self, Self::BeforeCchUa | Self::BeforeAcceptEncoding)
31    }
32}
33
34pub(crate) fn infer_anchor(name: &str) -> Option<HeaderAnchor> {
35    let lower = name.to_ascii_lowercase();
36    match lower.as_str() {
37        "origin" => Some(HeaderAnchor::AfterContentType),
38
39        "authorization" | "x-requested-with" | "x-csrf-token" | "x-requested-by" | "x-api-key" => {
40            Some(HeaderAnchor::AfterUserAgent)
41        }
42
43        _ => None,
44    }
45}
46
47#[cfg(test)]
48mod tests;