pub fn slice_subaddress(buffer: String) -> String {
let mut result = String::new();
for c in buffer.chars() {
if c == '\n' {
break;
} else {
result.push(c);
}
}
return result
.split_whitespace()
.skip(1)
.next()
.unwrap()
.replace("/", "")
.to_string();
}
pub fn redirect(url: String) -> String {
format!(
"HTTP/1.1 200 OK\r\n\r\n<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n <meta charset=\"utf-8\">\n<title>Redirecting...</title>\n<meta http-equiv=\"refresh\" content=\"0; URL='{}'\" /></head>",
url
)
}
pub enum HttpMethod {
NONE,
GET,
HEAD,
PUT,
POST,
PATCH,
DELETE,
CONNECT,
OPTIONS,
TRACE,
}
pub fn parse_http_method_unsafe(input: &[u8; 1024]) -> HttpMethod {
match input[0].to_ascii_uppercase() {
b'G' => return HttpMethod::GET,
b'H' => return HttpMethod::HEAD,
b'D' => return HttpMethod::DELETE,
b'C' => return HttpMethod::CONNECT,
b'O' => return HttpMethod::OPTIONS,
b'T' => return HttpMethod::TRACE,
b'P' => match input[1] {
b'U' => return HttpMethod::PUT,
b'O' => return HttpMethod::POST,
b'A' => return HttpMethod::PATCH,
_ => return HttpMethod::NONE,
},
_ => return HttpMethod::NONE,
};
}
pub fn parse_http_method_safe(input: &[u8; 1024]) -> HttpMethod {
match input[0] {
b'G' => {
if input.starts_with(b"GET ") {
return HttpMethod::GET;
}
}
b'H' => {
if input.starts_with(b"HEAD") {
return HttpMethod::HEAD;
}
}
b'D' => {
if input.starts_with(b"DELETE") {
return HttpMethod::DELETE;
}
}
b'C' => {
if input.starts_with(b"CONNECT") {
return HttpMethod::CONNECT;
}
}
b'O' => {
if input.starts_with(b"OPTIONS") {
return HttpMethod::OPTIONS;
}
}
b'T' => {
if input.starts_with(b"TRACE") {
return HttpMethod::TRACE;
}
}
b'P' => match input[1].to_ascii_uppercase() {
b'U' => {
if input.starts_with(b"PUT") {
return HttpMethod::PUT;
}
}
b'O' => {
if input.starts_with(b"POST") {
return HttpMethod::POST;
}
}
b'A' => {
if input.starts_with(b"PATCH") {
return HttpMethod::PATCH;
}
}
_ => return HttpMethod::NONE,
},
_ => return HttpMethod::NONE,
};
return HttpMethod::NONE;
}
#[cfg(test)]
fn parse_http_method_unsafe_test() {
let tests = [
("POST /", "post", "post"),
("PO ", "post", "none"),
("PUT /index", "put", "put"),
("PU", "put", "none"),
("OPTIONS ", "options", "options"),
("OP", "options", "none"),
("fhufqwvz87q", "none", "none"),
("PORTWINE IS DELICOUS", "post", "none"),
("post", "post", "none"),
];
for i in 0..6 {
assert_eq!(
http_method_to_string(parse_http_method_unsafe(&parse_http_method_test_helper(
tests[i].0.to_string()
))),
tests[i].1
);
}
for i in 0..6 {
assert_eq!(
http_method_to_string(parse_http_method_safe(&parse_http_method_test_helper(
tests[i].0.to_string()
))),
tests[i].2
);
}
}
#[cfg(test)]
fn parse_http_method_test_helper(input_string: String) -> [u8; 1024] {
let input_string: &[u8] = input_string.as_bytes();
let mut out = [0; 1024];
for i in 0..input_string.len() {
out[i] = input_string[i];
}
out
}
#[cfg(test)]
fn http_method_to_string(input: HttpMethod) -> String {
let out = match input {
HttpMethod::CONNECT => "connect",
HttpMethod::DELETE => "delete",
HttpMethod::GET => "get",
HttpMethod::HEAD => "head",
HttpMethod::NONE => "none",
HttpMethod::OPTIONS => "options",
HttpMethod::PATCH => "patcg",
HttpMethod::POST => "post",
HttpMethod::PUT => "put",
HttpMethod::TRACE => "trace",
};
out.to_string()
}
#[test]
fn test() {
parse_http_method_unsafe_test();
}