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
use mlua::{FromLua, Lua, Result, String as LuaString, Table, TableExt, TablePairs, ToLua, Value};
#[derive(Clone)]
pub struct Http<'lua>(Table<'lua>);
#[derive(Clone)]
pub struct Headers<'lua>(Table<'lua>);
impl<'lua> Http<'lua> {
pub fn req_get_headers(&self) -> Result<Headers> {
self.0.call_method("req_get_headers", ())
}
pub fn res_get_headers(&self) -> Result<Headers> {
self.0.call_method("res_get_headers", ())
}
pub fn req_add_header<V: ToLua<'lua>>(&self, name: &str, value: V) -> Result<()> {
self.0.call_method("req_add_header", (name, value))
}
pub fn res_add_header<V: ToLua<'lua>>(&self, name: &str, value: V) -> Result<()> {
self.0.call_method("res_add_header", (name, value))
}
pub fn req_del_header(&self, name: &str) -> Result<()> {
self.0.call_method("req_del_header", name)
}
pub fn res_del_header(&self, name: &str) -> Result<()> {
self.0.call_method("res_del_header", name)
}
pub fn req_set_header<V: ToLua<'lua>>(&self, name: &str, value: V) -> Result<()> {
self.0.call_method("req_set_header", (name, value))
}
pub fn res_set_header<V: ToLua<'lua>>(&self, name: &str, value: V) -> Result<()> {
self.0.call_method("res_set_header", (name, value))
}
pub fn req_rep_header(&self, name: &str, regex: &str, replace: &str) -> Result<()> {
self.0.call_method("req_rep_header", (name, regex, replace))
}
pub fn res_rep_header(&self, name: &str, regex: &str, replace: &str) -> Result<()> {
self.0.call_method("res_rep_header", (name, regex, replace))
}
pub fn req_set_method(&self, method: &str) -> Result<()> {
self.0.call_method("req_set_method", method)
}
pub fn req_set_path(&self, path: &str) -> Result<()> {
self.0.call_method("req_set_path", path)
}
pub fn req_set_query(&self, query: &str) -> Result<()> {
self.0.call_method("req_set_query", query)
}
pub fn req_set_uri(&self, uri: &str) -> Result<()> {
self.0.call_method("req_set_uri", uri)
}
pub fn res_set_status(&self, status: u16, reason: Option<&str>) -> Result<()> {
self.0.call_method("res_set_status", (status, reason))
}
}
impl<'lua> Headers<'lua> {
pub fn pairs(self) -> HeaderPairs<'lua> {
HeaderPairs(self.0.pairs())
}
pub fn get(&self, name: &str) -> Result<Vec<String>> {
let name = name.to_ascii_lowercase();
let mut result = Vec::new();
if let Some(values) = self.0.get::<_, Option<Table>>(name)? {
for v in values.pairs::<i32, LuaString>() {
result.push(String::from_utf8_lossy(v?.1.as_bytes()).into_owned());
}
}
Ok(result)
}
pub fn get_first(&self, name: &str) -> Result<Option<String>> {
let name = name.to_ascii_lowercase();
if let Some(values) = self.0.get::<_, Option<Table>>(name)? {
let val: LuaString = values.get(0)?;
return Ok(Some(String::from_utf8_lossy(val.as_bytes()).into_owned()));
}
Ok(None)
}
}
impl<'lua> FromLua<'lua> for Http<'lua> {
fn from_lua(value: Value<'lua>, lua: &'lua Lua) -> Result<Self> {
Ok(Http(Table::from_lua(value, lua)?))
}
}
impl<'lua> FromLua<'lua> for Headers<'lua> {
fn from_lua(value: Value<'lua>, lua: &'lua Lua) -> Result<Self> {
Ok(Headers(Table::from_lua(value, lua)?))
}
}
pub struct HeaderPairs<'lua>(TablePairs<'lua, LuaString<'lua>, Option<Table<'lua>>>);
impl<'lua> Iterator for HeaderPairs<'lua> {
type Item = Result<(String, Vec<String>)>;
fn next(&mut self) -> Option<Self::Item> {
match self.0.next() {
Some(Ok(item)) => {
let name = String::from_utf8_lossy(item.0.as_bytes()).into_owned();
let mut values = Vec::new();
if let Some(t) = item.1 {
for pair in t.pairs::<i32, LuaString>() {
match pair {
Ok((_, val)) => {
values.push(String::from_utf8_lossy(val.as_bytes()).into_owned());
}
Err(e) => return Some(Err(e)),
}
}
}
Some(Ok((name, values)))
}
Some(Err(e)) => Some(Err(e)),
None => None,
}
}
}