use super::collection::{Collection, HashMapCollection};
#[derive(Debug, Clone, Default)]
pub struct RequestData {
pub method: String,
pub uri: String,
pub uri_raw: String,
pub path: String,
pub query_string: String,
pub protocol: String,
pub headers: HashMapCollection,
pub args_get: HashMapCollection,
pub args_post: HashMapCollection,
pub cookies: HashMapCollection,
pub body: Vec<u8>,
pub client_ip: String,
pub client_port: u16,
pub server_name: String,
pub server_port: u16,
}
impl RequestData {
pub fn new() -> Self {
Self::default()
}
pub fn set_uri(&mut self, uri: &str) {
self.uri = uri.to_string();
self.uri_raw = uri.to_string();
if let Some(pos) = uri.find('?') {
self.path = uri[..pos].to_string();
self.query_string = uri[pos + 1..].to_string();
self.parse_query_string(&self.query_string.clone());
} else {
self.path = uri.to_string();
self.query_string.clear();
}
}
pub fn set_method(&mut self, method: &str) {
self.method = method.to_string();
}
pub fn set_protocol(&mut self, protocol: &str) {
self.protocol = protocol.to_string();
}
pub fn add_header(&mut self, name: &str, value: &str) {
self.headers.add(name.to_lowercase(), value.to_string());
}
pub fn append_body(&mut self, data: &[u8]) {
self.body.extend_from_slice(data);
}
pub fn body_str(&self) -> String {
String::from_utf8_lossy(&self.body).to_string()
}
pub fn body_length(&self) -> usize {
self.body.len()
}
fn parse_query_string(&mut self, qs: &str) {
for pair in qs.split('&') {
if let Some(pos) = pair.find('=') {
let key = &pair[..pos];
let value = &pair[pos + 1..];
let key = percent_encoding::percent_decode_str(key)
.decode_utf8_lossy()
.to_string();
let value = percent_encoding::percent_decode_str(value)
.decode_utf8_lossy()
.to_string();
self.args_get.add(key, value);
} else if !pair.is_empty() {
let key = percent_encoding::percent_decode_str(pair)
.decode_utf8_lossy()
.to_string();
self.args_get.add(key, String::new());
}
}
}
pub fn parse_form_body(&mut self) {
let body_str = self.body_str();
for pair in body_str.split('&') {
if let Some(pos) = pair.find('=') {
let key = &pair[..pos];
let value = &pair[pos + 1..];
let key = percent_encoding::percent_decode_str(key)
.decode_utf8_lossy()
.to_string();
let value = percent_encoding::percent_decode_str(value)
.decode_utf8_lossy()
.to_string();
self.args_post.add(key, value);
}
}
}
pub fn all_args(&self) -> Vec<(&str, &str)> {
let mut all = self.args_get.all();
all.extend(self.args_post.all());
all
}
}