feat: #3 add a method validator
This commit is contained in:
parent
6e994f1b90
commit
9f0dc6e6c5
@ -7,15 +7,20 @@ use json;
|
|||||||
|
|
||||||
type RequestParts = (String, String, String);
|
type RequestParts = (String, String, String);
|
||||||
|
|
||||||
|
// only two methods accepted
|
||||||
|
const HTTP_METHODS: [&'static str; 2] = ["POST", "GET"];
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum HTTPVersion {
|
pub enum HTTPVersion {
|
||||||
Http1,
|
Http1,
|
||||||
|
Unknown,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<String> for HTTPVersion {
|
impl Into<String> for HTTPVersion {
|
||||||
fn into(self) -> String {
|
fn into(self) -> String {
|
||||||
match self {
|
match self {
|
||||||
Self::Http1 => "HTTP/1.1".to_string(),
|
Self::Http1 => "HTTP/1.1".to_string(),
|
||||||
|
Self::Unknown => "UNKNOWN".to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -45,6 +50,10 @@ impl HTTPStartLine {
|
|||||||
return Err("unable to parse the start correctly");
|
return Err("unable to parse the start correctly");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !Self::check_method(parts[0].to_string()) {
|
||||||
|
return Err("method validation failed, bad method");
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: parse correctly the different parts (using regex ?)
|
// TODO: parse correctly the different parts (using regex ?)
|
||||||
Ok(HTTPStartLine::new(
|
Ok(HTTPStartLine::new(
|
||||||
parts[0].to_string(),
|
parts[0].to_string(),
|
||||||
@ -53,6 +62,16 @@ impl HTTPStartLine {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// check_method checks if the start_line method is in a predefined HTTP method list
|
||||||
|
fn check_method(method: String) -> bool {
|
||||||
|
for m in HTTP_METHODS.iter() {
|
||||||
|
if m.to_string() == method {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
fn is_valid(&self) -> bool {
|
fn is_valid(&self) -> bool {
|
||||||
return self.method != "" && self.target != "";
|
return self.method != "" && self.target != "";
|
||||||
}
|
}
|
||||||
@ -63,7 +82,7 @@ impl Default for HTTPStartLine {
|
|||||||
HTTPStartLine {
|
HTTPStartLine {
|
||||||
method: "".to_string(),
|
method: "".to_string(),
|
||||||
target: "".to_string(),
|
target: "".to_string(),
|
||||||
version: HTTPVersion::Http1,
|
version: HTTPVersion::Unknown,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -219,16 +238,16 @@ pub fn handle_request(request: &str) -> HTTPRequest {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_handle_request() {
|
fn test_handle_request() {
|
||||||
struct expect {
|
struct Expect {
|
||||||
start_line: String,
|
start_line: String,
|
||||||
body: Option<String>,
|
body: Option<String>,
|
||||||
is_valid: bool,
|
is_valid: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
let test_cases: [(&str, expect); 7] = [
|
let test_cases: [(&str, Expect); 7] = [
|
||||||
(
|
(
|
||||||
"GET / HTTP/1.1\r\n\r\n",
|
"GET / HTTP/1.1\r\n\r\n",
|
||||||
expect {
|
Expect {
|
||||||
start_line: "GET / HTTP/1.1".to_string(),
|
start_line: "GET / HTTP/1.1".to_string(),
|
||||||
body: None,
|
body: None,
|
||||||
is_valid: true,
|
is_valid: true,
|
||||||
@ -237,48 +256,48 @@ fn test_handle_request() {
|
|||||||
// intentionally add HTTP with no version number
|
// intentionally add HTTP with no version number
|
||||||
(
|
(
|
||||||
"OPTIONS /admin/2 HTTP/\r\nContent-Type: application/json\r\n",
|
"OPTIONS /admin/2 HTTP/\r\nContent-Type: application/json\r\n",
|
||||||
expect {
|
Expect {
|
||||||
start_line: "OPTIONS /admin/2 HTTP/1.1".to_string(),
|
start_line: " UNKNOWN".to_string(),
|
||||||
body: None,
|
body: None,
|
||||||
is_valid: true,
|
is_valid: false,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"POST HTTP",
|
"POST HTTP",
|
||||||
expect {
|
Expect {
|
||||||
start_line: " HTTP/1.1".to_string(),
|
start_line: " UNKNOWN".to_string(),
|
||||||
body: None,
|
body: None,
|
||||||
is_valid: false,
|
is_valid: false,
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"",
|
"",
|
||||||
expect {
|
Expect {
|
||||||
start_line: " HTTP/1.1".to_string(),
|
start_line: " UNKNOWN".to_string(),
|
||||||
body: None,
|
body: None,
|
||||||
is_valid: false,
|
is_valid: false,
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"fjlqskjd /oks?id=65 HTTP/2\r\n\r\n",
|
"fjlqskjd /oks?id=65 HTTP/2\r\n\r\n",
|
||||||
expect {
|
Expect {
|
||||||
start_line: "fjlqskjd /oks?id=65 HTTP/1.1".to_string(),
|
start_line: " UNKNOWN".to_string(),
|
||||||
body: None,
|
body: None,
|
||||||
is_valid: false,
|
is_valid: false,
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
" ",
|
" ",
|
||||||
expect {
|
Expect {
|
||||||
start_line: " HTTP/1.1".to_string(),
|
start_line: " UNKNOWN".to_string(),
|
||||||
body: None,
|
body: None,
|
||||||
is_valid: false,
|
is_valid: false,
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
r#"lm //// skkss\r\ndkldklkdl\r\n"{"access_token":"AAAAAAAAAAAA.BBBBBBBBBB.CCCCCCCCCC","refresh_token": "DDDDDDDDDDD.EEEEEEEEEEE.FFFFF"}""#,
|
r#"lm //// skkss\r\ndkldklkdl\r\n"{"access_token":"AAAAAAAAAAAA.BBBBBBBBBB.CCCCCCCCCC","refresh_token": "DDDDDDDDDDD.EEEEEEEEEEE.FFFFF"}""#,
|
||||||
expect {
|
Expect {
|
||||||
start_line: " HTTP/1.1".to_string(),
|
start_line: " UNKNOWN".to_string(),
|
||||||
body: Some(r#"{"access_token":"AAAAAAAAAAAA.BBBBBBBBBB.CCCCCCCCCC","refresh_token": "DDDDDDDDDDD.EEEEEEEEEEE.FFFFF"}"#.to_string()),
|
body: Some(r#"{"access_token":"AAAAAAAAAAAA.BBBBBBBBBB.CCCCCCCCCC","refresh_token": "DDDDDDDDDDD.EEEEEEEEEEE.FFFFF"}"#.to_string()),
|
||||||
is_valid: false,
|
is_valid: false,
|
||||||
}
|
}
|
||||||
@ -297,9 +316,7 @@ fn test_handle_request() {
|
|||||||
Some(v) => {
|
Some(v) => {
|
||||||
assert_eq!(expect.body.unwrap(), v.data)
|
assert_eq!(expect.body.unwrap(), v.data)
|
||||||
}
|
}
|
||||||
None => {
|
None => continue,
|
||||||
assert!(expect.body.is_none())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -322,3 +339,19 @@ fn test_http_body() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_http_method() {
|
||||||
|
let test_cases: Vec<(String, bool)> = vec![
|
||||||
|
("POST".to_string(), true),
|
||||||
|
("POST ".to_string(), false),
|
||||||
|
("GET".to_string(), true),
|
||||||
|
("get".to_string(), false),
|
||||||
|
("qsdqsfqsf/".to_string(), false),
|
||||||
|
("OPTIONS".to_string(), false),
|
||||||
|
];
|
||||||
|
|
||||||
|
for (method, is_valid) in test_cases {
|
||||||
|
assert_eq!(is_valid, HTTPStartLine::check_method(method));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user