1use std::fmt;
2
3use chromiumoxide::cdp::browser_protocol::network::{CookieParam, CookieSameSite, TimeSinceEpoch};
4
5use crate::Result;
6
7#[derive(Debug, Clone)]
9struct CookieFileParseError {
10 error_message: String,
11}
12impl CookieFileParseError {
13 fn new(error_message: String) -> CookieFileParseError {
14 CookieFileParseError {
15 error_message: error_message,
16 }
17 }
18}
19impl fmt::Display for CookieFileParseError {
20 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
21 write!(f, "Error parsing Cookie file: {}", self.error_message)
22 }
23}
24impl std::error::Error for CookieFileParseError {
25 fn description(&self) -> &str {
26 &self.error_message
27 }
28}
29
30pub fn parse_cookie_file(file_contents: &str) -> Result<Vec<CookieParam>> {
39 let mut cookies: Vec<CookieParam> = Vec::new();
40 for line_unchanged in file_contents.lines() {
42 let mut cookie_builder = CookieParam::builder().source_port(-1);
43 let mut line = line_unchanged;
44
45 if line.starts_with("#HttpOnly_") {
46 line = &line[10..];
47 cookie_builder = cookie_builder.http_only(true);
48 } else if line.starts_with("#") {
49 continue;
50 }
51
52 let cookie_args: Vec<&str> = line.split('\t').collect();
53 if cookie_args.len() != 7 {
54 tracing::error!(
55 "Error parsing cookie line (Wrong number of arguments): '{}'",
56 line
57 );
58 return Err(Box::new(CookieFileParseError::new(format!(
59 "Error parsing cookie line (Wrong number of arguments): '{}'",
60 line
61 ))));
62 }
63
64 cookie_builder = cookie_builder
65 .domain(cookie_args[0].to_string())
66 .same_site(if cookie_args[1].eq("TRUE") {
67 CookieSameSite::Strict
68 } else {
69 CookieSameSite::Lax
70 })
71 .path(cookie_args[2].to_string())
72 .http_only(cookie_args[3].eq("TRUE"))
73 .expires(TimeSinceEpoch::new(match cookie_args[4].parse::<f64>() {
74 Ok(value) => value,
75 Err(err) => {
76 return Err(Box::new(CookieFileParseError::new(format!(
77 "Error parsing cookie line: '{}' Could not convert time: '{}'",
78 line, err
79 ))));
80 }
81 }))
82 .name(cookie_args[5].to_string())
83 .value(cookie_args[6].to_string());
84
85 let cookie = cookie_builder.build()?;
86
87 tracing::trace!("Parsed cookie line: {:?} to {:?}", line_unchanged, cookie);
88
89 cookies.push(cookie);
90 }
91 Ok(cookies)
92}