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
139
use regex::Regex;
use std::sync::Arc;
use crate::http::*;
use crate::utils::ToRegex;
use crate::utils::RequestContinuation;
use crate::utils::RequestContinuation::*;
pub struct Builder {
stack: Vec<(MiddlewareRule, Box<Middleware>)>,
}
impl Builder {
pub fn new() -> Self {
Builder {
stack: Vec::new()
}
}
pub fn apply<M: 'static + Middleware>(mut self, m: M, include_path: Vec<&str>, exclude_path: Option<Vec<&str>>) -> Self {
let rule = MiddlewareRule::new(include_path, exclude_path);
let boxed_m = Box::new(m);
self.stack.push((rule, boxed_m));
self
}
pub fn build(self) -> MiddlewareStack {
let Builder {
stack,
} = self;
MiddlewareStack {
middlewares: Arc::new(stack),
}
}
}
pub struct MiddlewareStack {
middlewares: Arc<Vec<(MiddlewareRule, Box<Middleware>)>>
}
impl MiddlewareStack {
pub fn new() -> Self {
MiddlewareStack {
middlewares: Arc::new(Vec::new())
}
}
pub fn resolve(&self, req: &mut SyncRequest, res: &mut SyncResponse) -> RequestContinuation {
let path = req.uri().path().to_owned();
for &(ref rule, ref middleware) in self.middlewares.iter() {
if rule.validate_path(&path) {
if let Stop = middleware.resolve(req, res) {
return Stop;
}
}
}
Continue
}
}
impl Clone for MiddlewareStack {
fn clone(&self) -> Self {
MiddlewareStack {
middlewares: self.middlewares.clone(),
}
}
}
pub trait Middleware: Send + Sync {
fn resolve(&self, req: &mut SyncRequest, res: &mut SyncResponse) -> RequestContinuation;
}
struct MiddlewareRule {
included_path: Vec<Regex>,
excluded_path: Option<Vec<Regex>>,
}
impl MiddlewareRule {
pub fn new<R: ToRegex>(include_path: Vec<R>, exclude_path: Option<Vec<R>>) -> Self {
let mut included_path = Vec::new();
for include in include_path.iter() {
included_path.push(reg!(include));
}
let mut excluded_path: Option<Vec<Regex>> = Option::None;
if let Some(excludes) = exclude_path {
let mut excludes_vec = Vec::new();
for exclude in excludes.iter() {
excludes_vec.push(reg!(exclude));
}
excluded_path = Some(excludes_vec);
}
MiddlewareRule {
included_path,
excluded_path,
}
}
pub fn validate_path(&self, path: &str) -> bool {
let path_clone = path.clone();
if self.included_path.iter().enumerate().find(
move |&(_index, r)| {
r.is_match(path_clone)
}
).is_some() {
if let Some(ref excluded_path) = self.excluded_path {
return excluded_path.iter().enumerate().find(
move |&(_index, re)| {
re.is_match(path_clone)
}
).is_none();
} else {
return true;
}
}
false
}
}