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
use futures::Future;
use plugins::{Plugin, PluginData};
use hyper::header::Cookie as CookieHeader;
use hyper::header::SetCookie;
use cookie::Cookie;
use textnonce::TextNonce;
header! { (Dnt, "Dnt") => [String] }
header! { (Tk, "Tk") => [String] }
pub struct Session {
cookie_name: String,
secure: bool,
http_only: bool,
respect_dnt_ad_absurdum: bool,
}
impl Session
{
pub fn new(cookie_name: String, secure: bool, http_only: bool) -> Session {
Session {
cookie_name: cookie_name,
secure: secure,
http_only: http_only,
respect_dnt_ad_absurdum: false,
}
}
pub fn respect_dnt_ad_absurdum(&mut self) {
self.respect_dnt_ad_absurdum = true;
}
}
impl<S,E> Plugin<S,E> for Session
where S: 'static, E: 'static
{
fn handle(&self, mut data: PluginData<S>)
-> Box<Future<Item = PluginData<S>, Error = E>>
{
if self.respect_dnt_ad_absurdum {
let mut dnt = false;
if let Some(header) = data.request.headers().get::<Dnt>() {
match *header {
Dnt(ref s) => {
if &*s != "0" {
dnt = true;
}
},
}
}
if dnt {
data.session_id = None;
data.response.headers_mut().set(Tk("N".to_owned()));
return Box::new(::futures::future::ok(data));
}
}
let mut maybe_key: Option<String> = None;
if let Some(cookie_header) = data.request.headers().get::<CookieHeader>() {
if let Some(cookie_value) = cookie_header.get(&*self.cookie_name) {
maybe_key = Some(cookie_value.to_owned());
}
}
if let Some(key) = maybe_key {
data.session_id = Some(key.to_owned());
return Box::new(::futures::future::ok(data));
}
let key = TextNonce::new().into_string();
data.session_id = Some(key.clone());
let mut cookie = Cookie::new(self.cookie_name.clone(), key);
cookie.set_path("/");
cookie.set_secure(self.secure);
cookie.set_http_only(self.http_only);
data.response.headers_mut().set(
SetCookie(vec![ cookie.to_string() ]));
Box::new(::futures::future::ok(data))
}
}