use super::cookie::Cookie;
use super::MimeType;
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum ContentEncodingMethod {
Gzip,
Compress,
Deflate,
Br,
}
impl ContentEncodingMethod {
pub fn from_string(string: String) -> Option<ContentEncodingMethod> {
match string.as_str() {
"gzip" => Some(ContentEncodingMethod::Gzip),
"compress" => Some(ContentEncodingMethod::Compress),
"deflate" => Some(ContentEncodingMethod::Deflate),
"br" => Some(ContentEncodingMethod::Br),
_ => None,
}
}
pub fn to_string(&self) -> String {
match self {
ContentEncodingMethod::Gzip => String::from("gzip"),
ContentEncodingMethod::Compress => String::from("compress"),
ContentEncodingMethod::Deflate => String::from("deflate"),
ContentEncodingMethod::Br => String::from("br"),
}
}
}
#[derive(Clone, Debug, PartialEq)]
pub enum HTTPResponseHeaders {
ContentType(MimeType),
ContentLength(usize),
ContentEncoding(ContentEncodingMethod),
Server(String),
SetCookie(Cookie),
Location(String),
AccessControlAllowOrigin(String),
}
impl HTTPResponseHeaders {
pub fn from_string(string: String) -> Option<HTTPResponseHeaders> {
let mut parts = string.split(':').map(|x| x.trim_end().trim_start());
let left: &str = match parts.next() {
Some(n) => n,
None => return None,
};
let right: &str = match parts.next() {
Some(n) => n,
None => return None,
};
match left {
"Content-Type" => {
if let Some(n) = MimeType::from_string(right.to_string()) {
Some(HTTPResponseHeaders::ContentType(n))
} else {
None
}
}
"Content-Length" => {
if let Err(_) = right.parse::<usize>() {
None
} else {
Some(HTTPResponseHeaders::ContentLength(right.parse().unwrap()))
}
}
"Content-Encoding" => {
if let Some(n) = ContentEncodingMethod::from_string(right.to_string()) {
Some(HTTPResponseHeaders::ContentEncoding(n))
} else {
None
}
}
"Server" => Some(HTTPResponseHeaders::Server(right.to_string())),
"Set-Cookie" => match Cookie::from_string(right.to_string()) {
Some(n) => Some(HTTPResponseHeaders::SetCookie(n)),
None => None,
},
"Location" => Some(HTTPResponseHeaders::Location(right.to_string())),
"Access-Control-Allow-Origin" => Some(HTTPResponseHeaders::AccessControlAllowOrigin(
right.to_string(),
)),
_ => None,
}
}
pub fn to_string(&self) -> String {
match self {
HTTPResponseHeaders::ContentType(n) => format!("Content-Type: {}", n.to_string()),
HTTPResponseHeaders::ContentLength(n) => format!("Content-Length: {}", n),
HTTPResponseHeaders::ContentEncoding(n) => {
format!("Content-Encoding: {}", n.to_string())
}
HTTPResponseHeaders::Server(n) => format!("Server: {}", n),
HTTPResponseHeaders::SetCookie(n) => format!("Set-Cookie: {}", n.to_string()),
HTTPResponseHeaders::Location(n) => format!("Location: {}", n),
HTTPResponseHeaders::AccessControlAllowOrigin(n) => {
format!("Access-Control-Allow-Origin: {}", n)
}
}
}
}
#[derive(Clone, Debug)]
pub enum HTTPRequestHeaders {
ContentLength(usize),
ContentType(MimeType),
Accept(MimeType),
UserAgent(String),
Cookie(Vec<Cookie>),
Host(String),
}
impl HTTPRequestHeaders {
pub fn from_string(string: String) -> Option<HTTPRequestHeaders> {
let mut parts = string.split(':');
let key = match parts.next() {
Some(n) => n,
None => {
return None;
}
};
let value = match parts.next() {
Some(n) => n,
None => {
return None;
}
};
let value = value.trim_end();
let value = value.trim_start();
match key {
"Content-Length" => {
if let Err(_) = value.parse::<usize>() {
return None;
}
Some(HTTPRequestHeaders::ContentLength(value.parse().unwrap()))
}
"Content-Type" => {
if let Some(m) = MimeType::from_string(value.to_string()) {
return Some(HTTPRequestHeaders::ContentType(m));
} else {
return None;
}
}
"Accept" => {
if let Some(m) = MimeType::from_string(value.to_string()) {
return Some(HTTPRequestHeaders::ContentType(m));
} else {
return None;
}
}
"User-Agent" => Some(HTTPRequestHeaders::UserAgent(value.to_string())),
"Cookie" => {
let parts: Vec<String> = value.split("; ").map(|x| x.to_string()).collect();
let mut cookies: Vec<Cookie> = Vec::new();
for part in parts {
if let Some(cookie) = Cookie::from_string(part) {
cookies.push(cookie);
}
}
Some(HTTPRequestHeaders::Cookie(cookies))
}
"Host" => Some(HTTPRequestHeaders::Host(value.to_string())),
_ => None,
}
}
}
pub fn req_headers_from_string(string: String) -> Vec<HTTPRequestHeaders> {
let mut out: Vec<HTTPRequestHeaders> = Vec::new();
for line in string.lines() {
if let Some(n) = HTTPRequestHeaders::from_string(line.to_string()) {
out.push(n);
}
}
out
}