1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
use hex::encode; use std::fmt::{Display, Formatter, Result as FmtResult}; use thiserror::Error; pub const CLIENT_COOKIE_LENGTH: usize = 8; pub const MINIMUM_SERVER_COOKIE_LENGTH: usize = 8; pub const MAXIMUM_SERVER_COOKIE_LENGTH: usize = 32; #[derive(Debug, PartialEq, Clone, Eq, Hash)] pub struct Cookie { pub client_cookie: [u8; 8], server_cookie: Option<Vec<u8>>, } #[derive(Debug, Clone, PartialEq, Eq, Hash, Error)] pub enum CookieError { #[error("Server cookie length is not between {MINIMUM_SERVER_COOKIE_LENGTH} and {MAXIMUM_SERVER_COOKIE_LENGTH}: {0}]")] ServerCookieLength(usize), } impl Cookie { pub fn new( client_cookie: [u8; 8], server_cookie: Option<Vec<u8>>, ) -> Result<Cookie, CookieError> { let mut cookie = Cookie { client_cookie, server_cookie: None, }; cookie.set_server_cookie(server_cookie)?; Ok(cookie) } pub fn set_server_cookie(&mut self, server_cookie: Option<Vec<u8>>) -> Result<(), CookieError> { match server_cookie { Some(server_cookie) => { let server_cookie_len = server_cookie.len(); if (MINIMUM_SERVER_COOKIE_LENGTH..MAXIMUM_SERVER_COOKIE_LENGTH) .contains(&server_cookie_len) { self.server_cookie.replace(server_cookie); Ok(()) } else { Err(CookieError::ServerCookieLength(server_cookie_len)) } } None => { self.server_cookie.take(); Ok(()) } } } pub fn get_server_cookie(&self) -> Option<&[u8]> { self.server_cookie.as_deref() } } impl Display for Cookie { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { write!(f, "Cookie {}", encode(self.client_cookie))?; match &self.server_cookie { Some(server_cookie) => write!(f, " {}", encode(server_cookie)), None => Ok(()), } } }