use std::collections::HashMap;
use std::net::SocketAddr;
use crate::{Method, Url};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Request {
pub ip: SocketAddr,
pub url: String,
pub method: Method,
pub body: String,
pub headers: HashMap<String, String>,
}
impl Request {
pub fn new(text: impl ToString, ip: SocketAddr) -> Option<Self> {
let text = text.to_string();
let mut lines = text.lines();
let first_line = lines.next()?;
let mut parts = first_line.split_whitespace();
let method = Method::from(parts.next()?.to_string());
let url = parts.next()?.into();
let mut headers = HashMap::with_capacity(12);
let mut in_body = false;
let mut body = String::default();
for line in lines {
match (in_body, line.is_empty()) {
(false, true) => in_body = true,
(true, _) => body.push_str(line),
_ => {
let parts = line.split_once(':')?;
let key = parts.0.into();
let value = parts.0.trim().into();
headers.insert(key, value);
}
}
}
Some(Self {
ip,
url,
method,
body,
headers,
})
}
pub fn get_header(&self, key: &str) -> Option<&str> {
self.headers.get(key).map(|s| s.as_str())
}
pub fn get_header_or(&self, key: &str, default: &'static str) -> &str {
self.get_header(key).unwrap_or(default)
}
pub fn set_header<T: ToString, K: ToString>(&mut self, k: T, v: K) {
self.headers.insert(k.to_string(), v.to_string());
}
pub fn parse_url(&self) -> Url {
self.url.as_str().into()
}
}