Skip to main content

rama_http_headers/privacy/
gpc.rs

1use crate::{HeaderDecode, HeaderEncode, TypedHeader};
2use rama_core::telemetry::tracing;
3use rama_http_types::{HeaderName, HeaderValue};
4
5#[derive(Debug, Default, Clone, Copy)]
6#[non_exhaustive]
7/// The `Sec-GPC` header, or the Global Privacy Control header.
8///
9/// It is an HTTP response and request header used specifically to allow the user to
10/// communicate their privacy preferences to the server.
11///
12/// This enables the user to exercise control over the privacy of their personal
13/// information against tracking, data selling, or adverse uses.
14pub struct SecGpc;
15
16impl SecGpc {
17    /// Create a new [`SecGpc`] typed header.
18    #[must_use]
19    pub fn new() -> Self {
20        Self
21    }
22}
23
24impl TypedHeader for SecGpc {
25    fn name() -> &'static HeaderName {
26        &rama_http_types::header::SEC_GPC
27    }
28}
29
30impl HeaderDecode for SecGpc {
31    fn decode<'i, I>(values: &mut I) -> Result<Self, crate::Error>
32    where
33        I: Iterator<Item = &'i HeaderValue>,
34    {
35        let value = values.next().ok_or_else(crate::Error::invalid)?;
36
37        if value == "0" {
38            tracing::debug!("unexpected Sec-Gpc header value of 0; only 1 is expected");
39            Err(crate::Error::invalid())
40        } else if value == "1" {
41            Ok(Self)
42        } else {
43            Err(crate::Error::invalid())
44        }
45    }
46}
47
48impl HeaderEncode for SecGpc {
49    fn encode<E>(&self, values: &mut E)
50    where
51        E: Extend<HeaderValue>,
52    {
53        let value = HeaderValue::from_static("1");
54        values.extend(std::iter::once(value));
55    }
56}