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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
//! # browsercookie-rs
//!
//! Browsercookie-rs crate allows you to gather cookies from browsers
//! on the system and return them in a CookieJar, so that it can be
//! used with other http libraries like Hyper etc..
//!
//! ```rust,ignore
//! use Browsercookie::{Browser, Browsercookies};
//!
//! let mut bc = Browsercookies::new();
//! let domain_regex = Regex::new(".*");
//! bc.from_browser(Browser::Firefox, &domain_regex).expect("Failed to get firefox browser cookies");
//! if let Ok(cookie_header) = bc.to_header(&domain_regex) as Result<String, Box<Error>> {
//!     println!("Cookies extracted");
//! }
//! ```
//!
//! Using above `to_header` returns a string to be used with http clients as a header
//! directly.
//!
//! ```rust,ignore
//! use reqwest::header;
//! use Browsercookie::{Browser, Browsercookies};
//!
//! let mut bc = Browsercookies::new();
//! let domain_regex = Regex::new("www.rust-lang.org");
//! bc.from_browser(Browser::Firefox, &domain_regex).expect("Failed to get firefox browser cookies");
//!
//! if let Ok(cookie_header) = bc.to_header(&domain_regex) as Result<String, Box<Error>> {
//!     let mut headers = header::HeaderMap::new();
//!     headers.insert(header::COOKIE, header::HeaderValue::from_str(&cookie_header));
//!
//!     let client = reqwest::Client::builder()
//!         .default_headers(headers)
//!         .build()?;
//!     let res = client.get("https://www.rust-lang.org").send()?;
//! }
//! ```
use regex::Regex;
use cookie::CookieJar;
use std::error::Error;

#[macro_use] extern crate serde;

mod firefox;
pub mod errors;

/// All supported browsers
pub enum Browser {
    Firefox
}

/// Main struct facilitating operations like collection & parsing of cookies from browsers
pub struct Browsercookies {
    pub cj: Box<CookieJar>
}

impl Browsercookies {
    pub fn new() -> Browsercookies {
        Browsercookies {
            cj: Box::new(CookieJar::new())
        }
    }

    pub fn from_browser(&mut self, b: Browser, domain_regex: &Regex) -> Result<(), Box<Error>> {
        match b {
            Browser::Firefox => return firefox::load(&mut self.cj, domain_regex)
        }
    }

    pub fn to_header(&self, domain_regex: &Regex) -> Result<String, Box<Error>> {
        let mut header = String::from("");
        for cookie in self.cj.iter() {
            if domain_regex.is_match(cookie.domain().unwrap()) {
                header.push_str(&format!("{}={}; ", cookie.name(), cookie.value()));
            }
        }
        Ok(header)
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_firefox() {
        let mut bc = Browsercookies::new();
        let domain_regex = Regex::new(".*").unwrap();
        bc.from_browser(Browser::Firefox, &domain_regex).expect("Failed to get firefox browser cookies");
        if let Ok(cookie_header) = bc.to_header(&domain_regex) as Result<String, Box<Error>> {
            assert_eq!(cookie_header, "name=value; ");
        }
    }
}