fix encapsulation by adding getters + add json extraction value function
This commit is contained in:
		
							parent
							
								
									0c7b0bec12
								
							
						
					
					
						commit
						ad4fdc300d
					
				
							
								
								
									
										10
									
								
								src/body.rs
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								src/body.rs
									
									
									
									
									
								
							| @ -1,20 +1,20 @@ | ||||
| use json; | ||||
| use json::JsonValue; | ||||
| 
 | ||||
| const NULL_CHAR: &'static str = "\0"; | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct HTTPBody { | ||||
|     data: json::JsonValue, | ||||
|     data: JsonValue, | ||||
| } | ||||
| 
 | ||||
| /// HTTPBody represents an HTTP request body
 | ||||
| /// for simplicity, only json body is allowed
 | ||||
| /// for simplicity, only JSON body is allowed
 | ||||
| impl HTTPBody { | ||||
|     fn new(data: json::JsonValue) -> HTTPBody { | ||||
|     fn new(data: JsonValue) -> HTTPBody { | ||||
|         HTTPBody { data } | ||||
|     } | ||||
| 
 | ||||
|     pub fn get_data(&self) -> &json::JsonValue { | ||||
|     pub fn get_data(&self) -> &JsonValue { | ||||
|         &self.data | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -3,6 +3,9 @@ | ||||
| //!
 | ||||
| //! see: https://developer.mozilla.org/en-US/docs/Web/HTTP/Messages
 | ||||
| //! NOTE: only few parts of the specification has been implemented
 | ||||
| //!
 | ||||
| //! * Only json body allowed
 | ||||
| //! * HTTP Headers not parsed
 | ||||
| 
 | ||||
| mod body; | ||||
| mod request; | ||||
|  | ||||
| @ -1,3 +1,4 @@ | ||||
| use json::{object::Object, JsonValue}; | ||||
| use std::collections::VecDeque; | ||||
| 
 | ||||
| use crate::{HTTPBody, HTTPStartLine}; | ||||
| @ -9,10 +10,8 @@ const HTTP_REQUEST_SEPARATOR: &'static str = "\r\n"; | ||||
| /// HTTPRequest represents an HTTP request (headers are not parsed)
 | ||||
| #[derive(Debug)] | ||||
| pub struct HTTPRequest<'a> { | ||||
|     pub start_line: HTTPStartLine<'a>, | ||||
|     pub body: Option<HTTPBody>, | ||||
|     // includes the client IP + port (should be in the headers)
 | ||||
|     pub addr: String, | ||||
|     start_line: HTTPStartLine<'a>, | ||||
|     body: Option<HTTPBody>, | ||||
| } | ||||
| 
 | ||||
| impl<'a> HTTPRequest<'a> { | ||||
| @ -55,6 +54,25 @@ impl<'a> HTTPRequest<'a> { | ||||
|             Err(e) => Err(e.to_string()), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// get_bodyèvalue retrieves JSON value in `HTTPBody`
 | ||||
|     pub fn get_body_value(&self, key: &str) -> Option<String> { | ||||
|         match self.body { | ||||
|             Some(ref b) => match &b.get_data() { | ||||
|                 JsonValue::Object(d) => extract_json_value(&d, key), | ||||
|                 _ => None, | ||||
|             }, | ||||
|             None => None, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn get_target(&self) -> &str { | ||||
|         self.start_line.get_target() | ||||
|     } | ||||
| 
 | ||||
|     pub fn get_method(&self) -> &str { | ||||
|         self.start_line.get_method() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<'a> Default for HTTPRequest<'a> { | ||||
| @ -62,7 +80,6 @@ impl<'a> Default for HTTPRequest<'a> { | ||||
|         HTTPRequest { | ||||
|             start_line: HTTPStartLine::default(), | ||||
|             body: None, | ||||
|             addr: "".to_string(), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -79,6 +96,17 @@ impl<'a> From<&'a str> for HTTPRequest<'a> { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /// extract_json_value extracts JSON value from a key
 | ||||
| pub fn extract_json_value(data: &Object, key: &str) -> Option<String> { | ||||
|     match data.get(key) { | ||||
|         Some(u) => match u.as_str() { | ||||
|             Some(s) => return Some(s.to_string()), | ||||
|             None => None, | ||||
|         }, | ||||
|         None => None, | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| fn test_request() { | ||||
|     struct Expect<'a> { | ||||
| @ -189,7 +217,6 @@ fn test_request() { | ||||
| 
 | ||||
|     for (request, expect) in test_cases { | ||||
|         let http_request = HTTPRequest::from(request); | ||||
|         println!("{}", request); | ||||
|         assert_eq!(expect.is_valid, http_request.start_line.is_valid()); | ||||
| 
 | ||||
|         let start_line: String = http_request.start_line.into(); | ||||
| @ -203,3 +230,21 @@ fn test_request() { | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| fn test_extract_json_value() { | ||||
|     let test_cases: [(JsonValue, bool, bool); 3] = [ | ||||
|         (json::parse(r#"{"test": ""}"#).unwrap(), true, true), | ||||
|         (json::parse(r#"{}"#).unwrap(), true, false), | ||||
|         (json::parse(r#"[]"#).unwrap(), false, false), | ||||
|     ]; | ||||
| 
 | ||||
|     for (value, is_valid, has_key) in test_cases { | ||||
|         match value { | ||||
|             json::JsonValue::Object(d) => { | ||||
|                 assert_eq!(has_key, extract_json_value(&d, "test").is_some()); | ||||
|             } | ||||
|             _ => assert!(!is_valid), | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -42,6 +42,14 @@ impl<'a> HTTPStartLine<'a> { | ||||
|         )) | ||||
|     } | ||||
| 
 | ||||
|     pub fn get_target(&self) -> &str { | ||||
|         self.target | ||||
|     } | ||||
| 
 | ||||
|     pub fn get_method(&self) -> &str { | ||||
|         self.method | ||||
|     } | ||||
| 
 | ||||
|     pub fn is_valid(&self) -> bool { | ||||
|         return self.method != "" && self.target != "" && self.version != HTTPVersion::Unknown; | ||||
|     } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user