netscape-cookie-file-parser 0.3.0

Parse Netscape/curl cookie jar files while preserving raw cookie bytes.
Documentation
/// One parsed cookie record from a Netscape cookie file.
///
/// String-like fields are byte buffers rather than `String`s because cookie jar
/// files seen in the wild may contain non-UTF-8 octets.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Cookie {
    /// Cookie domain bytes with one leading dot removed.
    pub domain: Vec<u8>,
    /// Whether the original tail-match field was `TRUE`, case-insensitively.
    pub tail_match: bool,
    /// Raw cookie path field bytes.
    pub path: Vec<u8>,
    /// Whether the original secure field was `TRUE`, case-insensitively.
    pub secure: bool,
    /// Expiration timestamp parsed as an unsigned integer.
    pub expires: u64,
    /// Raw cookie name bytes.
    pub name: Vec<u8>,
    /// Raw cookie value bytes.
    pub value: Vec<u8>,
    /// Whether this line used curl's `#HttpOnly_` cookie marker.
    pub http_only: bool,
    /// Recognized security prefix in the cookie name.
    pub prefix: CookiePrefix,
}

/// Case-sensitive cookie name prefixes recognized by the parser.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CookiePrefix {
    /// No recognized cookie prefix.
    None,
    /// Cookie name starts with `__Secure-`.
    Secure,
    /// Cookie name starts with `__Host-`.
    Host,
}

// The prefix checks are intentionally case-sensitive: cookie prefixes are part
// of the cookie name contract, not ordinary case-insensitive cookie metadata.
pub(crate) fn cookie_prefix(name: &[u8]) -> CookiePrefix {
    if name.starts_with(b"__Secure-") {
        CookiePrefix::Secure
    } else if name.starts_with(b"__Host-") {
        CookiePrefix::Host
    } else {
        CookiePrefix::None
    }
}