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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
use cookie_crate;
use header;
use std::borrow::Cow;
use std::fmt;
use std::time::SystemTime;
fn tm_to_systemtime(tm: ::time::Tm) -> SystemTime {
let seconds = tm.to_timespec().sec;
let duration = std::time::Duration::from_secs(seconds.abs() as u64);
if seconds > 0 {
SystemTime::UNIX_EPOCH + duration
} else {
SystemTime::UNIX_EPOCH - duration
}
}
pub struct CookieParseError(cookie::ParseError);
impl<'a> fmt::Debug for CookieParseError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.fmt(f)
}
}
impl<'a> fmt::Display for CookieParseError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.fmt(f)
}
}
impl std::error::Error for CookieParseError {}
pub struct Cookie<'a>(cookie::Cookie<'a>);
impl<'a> fmt::Debug for Cookie<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.fmt(f)
}
}
impl Cookie<'static> {
pub fn new<N, V>(name: N, value: V) -> Self
where
N: Into<Cow<'static, str>>,
V: Into<Cow<'static, str>>,
{
Cookie(cookie::Cookie::new(name, value))
}
}
impl<'a> Cookie<'a> {
fn parse(value: &'a ::header::HeaderValue) -> Result<Cookie<'a>, CookieParseError> {
std::str::from_utf8(value.as_bytes())
.map_err(cookie::ParseError::from)
.and_then(cookie::Cookie::parse)
.map_err(CookieParseError)
.map(Cookie)
}
pub(crate) fn into_inner(self) -> cookie::Cookie<'a> {
self.0
}
pub fn name(&self) -> &str {
self.0.name()
}
pub fn value(&self) -> &str {
self.0.value()
}
pub fn http_only(&self) -> bool {
self.0.http_only().unwrap_or(false)
}
pub fn secure(&self) -> bool {
self.0.secure().unwrap_or(false)
}
pub fn same_site_lax(&self) -> bool {
self.0.same_site() == Some(cookie_crate::SameSite::Lax)
}
pub fn same_site_strict(&self) -> bool {
self.0.same_site() == Some(cookie_crate::SameSite::Strict)
}
pub fn path(&self) -> Option<&str> {
self.0.path()
}
pub fn domain(&self) -> Option<&str> {
self.0.domain()
}
pub fn max_age(&self) -> Option<std::time::Duration> {
self.0.max_age().map(|d| std::time::Duration::new(d.num_seconds() as u64, 0))
}
pub fn expires(&self) -> Option<SystemTime> {
self.0.expires().map(tm_to_systemtime)
}
}
pub(crate) fn extract_response_cookies<'a>(
headers: &'a hyper::HeaderMap,
) -> impl Iterator<Item = Result<Cookie<'a>, CookieParseError>> + 'a {
headers
.get_all(header::SET_COOKIE)
.iter()
.map(|value| Cookie::parse(value))
}
#[derive(Default)]
pub(crate) struct CookieStore(pub(crate) ::cookie_store::CookieStore);
impl<'a> fmt::Debug for CookieStore {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.fmt(f)
}
}