1use std::{
2 collections::HashMap,
3 str,
4};
5
6use log::{warn};
7pub use cookie::Cookie;
8
9use crate::{
10 Request,
11 Response,
12};
13
14pub struct Cookies<'c> {
15 cookies: HashMap<String, Cookie<'c>>,
16 cookies_to_set: Vec<Cookie<'c>>,
17}
18
19impl<'a> Cookies<'a> {
20 pub fn new(req: &'a Request) -> Self {
21 let mut cookies = HashMap::default();
22 let iter_cookies = req.headers.get("Cookie");
23 if iter_cookies.is_none() {
24 return Cookies{
25 cookies,
26 cookies_to_set: vec!(),
27 }
28 }
29 for cookie in iter_cookies.unwrap().split(|x| *x == b';') {
30 let cookie = match str::from_utf8(cookie) {
31 Ok(s) => s,
32 Err(_) => {
33 warn!("Invalid cookie being ignored!");
34 continue;
35 }
36 };
37 let cookie = Cookie::parse_encoded(cookie);
38 if cookie.is_err() {
39 warn!("Invalid cookie being ignored!");
40 continue;
41 }
42 let cookie = cookie.unwrap();
43 cookies.insert(String::from(cookie.name()), cookie);
44 }
45 Cookies {
46 cookies,
47 cookies_to_set: vec!(),
48 }
49 }
50
51 pub fn get(&self, s: &str) -> Option<&'a Cookie> {
52 self.cookies.get(s)
53 }
54
55 pub fn add_cookie(&mut self, cookie: Cookie<'a>) {
56 self.cookies_to_set.push(cookie.clone());
57 self.cookies.insert(String::from(cookie.name()), cookie);
58 }
59
60 pub fn write_cookies(&self, resp: &mut Response) {
61 for cookie in &self.cookies_to_set {
62 resp.headers.push(("Set-Cookie".into(), Vec::from(format!("{}", cookie.encoded()))));
63 }
64 }
65}