sentinel_modsec/variables/
request.rs1use super::collection::{Collection, HashMapCollection};
4
5#[derive(Debug, Clone, Default)]
7pub struct RequestData {
8 pub method: String,
10 pub uri: String,
12 pub uri_raw: String,
14 pub path: String,
16 pub query_string: String,
18 pub protocol: String,
20 pub headers: HashMapCollection,
22 pub args_get: HashMapCollection,
24 pub args_post: HashMapCollection,
26 pub cookies: HashMapCollection,
28 pub body: Vec<u8>,
30 pub client_ip: String,
32 pub client_port: u16,
34 pub server_name: String,
36 pub server_port: u16,
38}
39
40impl RequestData {
41 pub fn new() -> Self {
43 Self::default()
44 }
45
46 pub fn set_uri(&mut self, uri: &str) {
48 self.uri = uri.to_string();
49 self.uri_raw = uri.to_string();
50
51 if let Some(pos) = uri.find('?') {
52 self.path = uri[..pos].to_string();
53 self.query_string = uri[pos + 1..].to_string();
54 self.parse_query_string(&self.query_string.clone());
55 } else {
56 self.path = uri.to_string();
57 self.query_string.clear();
58 }
59 }
60
61 pub fn set_method(&mut self, method: &str) {
63 self.method = method.to_string();
64 }
65
66 pub fn set_protocol(&mut self, protocol: &str) {
68 self.protocol = protocol.to_string();
69 }
70
71 pub fn add_header(&mut self, name: &str, value: &str) {
73 self.headers.add(name.to_lowercase(), value.to_string());
74 }
75
76 pub fn append_body(&mut self, data: &[u8]) {
78 self.body.extend_from_slice(data);
79 }
80
81 pub fn body_str(&self) -> String {
83 String::from_utf8_lossy(&self.body).to_string()
84 }
85
86 pub fn body_length(&self) -> usize {
88 self.body.len()
89 }
90
91 fn parse_query_string(&mut self, qs: &str) {
93 for pair in qs.split('&') {
94 if let Some(pos) = pair.find('=') {
95 let key = &pair[..pos];
96 let value = &pair[pos + 1..];
97 let key = percent_encoding::percent_decode_str(key)
99 .decode_utf8_lossy()
100 .to_string();
101 let value = percent_encoding::percent_decode_str(value)
102 .decode_utf8_lossy()
103 .to_string();
104 self.args_get.add(key, value);
105 } else if !pair.is_empty() {
106 let key = percent_encoding::percent_decode_str(pair)
107 .decode_utf8_lossy()
108 .to_string();
109 self.args_get.add(key, String::new());
110 }
111 }
112 }
113
114 pub fn parse_form_body(&mut self) {
116 let body_str = self.body_str();
117 for pair in body_str.split('&') {
118 if let Some(pos) = pair.find('=') {
119 let key = &pair[..pos];
120 let value = &pair[pos + 1..];
121 let key = percent_encoding::percent_decode_str(key)
122 .decode_utf8_lossy()
123 .to_string();
124 let value = percent_encoding::percent_decode_str(value)
125 .decode_utf8_lossy()
126 .to_string();
127 self.args_post.add(key, value);
128 }
129 }
130 }
131
132 pub fn all_args(&self) -> Vec<(&str, &str)> {
134 let mut all = self.args_get.all();
135 all.extend(self.args_post.all());
136 all
137 }
138}