#8 update the doc
This commit is contained in:
parent
384e868501
commit
13b515c9c7
@ -1,3 +1,5 @@
|
|||||||
|
//! handlers module includes tools to parse an HTTP request and build and HTTP response
|
||||||
|
|
||||||
pub mod request;
|
pub mod request;
|
||||||
pub mod response;
|
pub mod response;
|
||||||
|
|
||||||
|
|||||||
@ -99,7 +99,7 @@ impl HTTPStartLine {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// check_method checks if the start_line method is in a predefined HTTP method list
|
/// checks if the start_line method is in a predefined HTTP method list
|
||||||
fn check_method(method: &String) -> bool {
|
fn check_method(method: &String) -> bool {
|
||||||
for m in HTTP_METHODS.iter() {
|
for m in HTTP_METHODS.iter() {
|
||||||
if m.to_string() == *method {
|
if m.to_string() == *method {
|
||||||
@ -109,7 +109,7 @@ impl HTTPStartLine {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
/// check_target checks if the start_line target is in a predefined HTTP target whitelist
|
/// checks if the start_line target is in a predefined HTTP target whitelist
|
||||||
fn check_target(target: &String) -> bool {
|
fn check_target(target: &String) -> bool {
|
||||||
for t in HTTP_TARGETS.iter() {
|
for t in HTTP_TARGETS.iter() {
|
||||||
if t.to_string() == *target {
|
if t.to_string() == *target {
|
||||||
@ -145,7 +145,7 @@ impl Into<String> for HTTPStartLine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// HTTPBody represents http request body
|
/// represents an HTTP request body
|
||||||
/// for simplicity, only json body is accepted
|
/// for simplicity, only json body is accepted
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct HTTPBody {
|
pub struct HTTPBody {
|
||||||
@ -176,7 +176,7 @@ impl TryFrom<String> for HTTPBody {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Request defined the HTTP request
|
/// Represents an HTTP request (headers are not parsed)
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct HTTPRequest {
|
pub struct HTTPRequest {
|
||||||
pub start_line: HTTPStartLine,
|
pub start_line: HTTPStartLine,
|
||||||
@ -209,7 +209,7 @@ impl HTTPRequest {
|
|||||||
Ok((start_line, request_parts, body))
|
Ok((start_line, request_parts, body))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// parse parses the request by spliting the incoming request with the separator `\r\n`
|
/// parse the request by spliting the incoming request with the separator `\r\n`
|
||||||
fn parse(request: &str) -> Result<HTTPRequest, String> {
|
fn parse(request: &str) -> Result<HTTPRequest, String> {
|
||||||
let request = request.to_string();
|
let request = request.to_string();
|
||||||
|
|
||||||
@ -264,7 +264,7 @@ impl From<&str> for HTTPRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_request(request: &str) -> HTTPRequest {
|
pub fn handle_request(request: &str) -> HTTPRequest {
|
||||||
return HTTPRequest::from(request);
|
HTTPRequest::from(request)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
@ -58,6 +58,8 @@ impl HTTPStatusLine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// represents an HTTP response (headers are not parsed)
|
||||||
|
/// NOTE: for simplicity, only JSON body are accepted
|
||||||
pub struct HTTPResponse {
|
pub struct HTTPResponse {
|
||||||
status_line: HTTPStatusLine,
|
status_line: HTTPStatusLine,
|
||||||
body: json::JsonValue,
|
body: json::JsonValue,
|
||||||
@ -89,8 +91,9 @@ impl Into<String> for HTTPResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl HTTPResponse {
|
impl HTTPResponse {
|
||||||
// `From<T>` could be used instead of forcing it like this
|
/// creates a response from the incoming `Request`
|
||||||
// it fails using `async_trait` attributes (only custom traits work ?)
|
/// `From<T>` could be used instead of forcing it like this
|
||||||
|
/// it fails using `async_trait` attributes (only custom traits work ?)
|
||||||
pub async fn from(request: HTTPRequest) -> Self {
|
pub async fn from(request: HTTPRequest) -> Self {
|
||||||
let mut response = HTTPResponse::default();
|
let mut response = HTTPResponse::default();
|
||||||
if !request.is_valid() {
|
if !request.is_valid() {
|
||||||
@ -125,7 +128,7 @@ impl HTTPResponse {
|
|||||||
response
|
response
|
||||||
}
|
}
|
||||||
|
|
||||||
/// as_403 generates a 403 response with a correct error message
|
/// generates a 403 response with a correct error message
|
||||||
pub fn as_403() -> Self {
|
pub fn as_403() -> Self {
|
||||||
let mut response = HTTPResponse {
|
let mut response = HTTPResponse {
|
||||||
status_line: HTTPStatusLine::default(),
|
status_line: HTTPStatusLine::default(),
|
||||||
|
|||||||
@ -21,6 +21,7 @@ async fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// parses the incoming request (partial spec implementation) and build an HTTP response
|
||||||
async fn handle_connection(mut stream: TcpStream) {
|
async fn handle_connection(mut stream: TcpStream) {
|
||||||
let mut buffer: [u8; 1024] = [0; 1024];
|
let mut buffer: [u8; 1024] = [0; 1024];
|
||||||
let n = stream.read(&mut buffer).await.unwrap();
|
let n = stream.read(&mut buffer).await.unwrap();
|
||||||
|
|||||||
@ -8,7 +8,7 @@ use tokio::io::AsyncReadExt; // for read_to_end()
|
|||||||
|
|
||||||
use super::store::{Credentials, Store};
|
use super::store::{Credentials, Store};
|
||||||
|
|
||||||
/// FileStore references a `store` file
|
/// references a credentials store file
|
||||||
pub struct FileStore {
|
pub struct FileStore {
|
||||||
path: String,
|
path: String,
|
||||||
credentials: Vec<Credentials>,
|
credentials: Vec<Credentials>,
|
||||||
@ -22,7 +22,7 @@ impl FileStore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// parse_contents loads and reads the file asynchonously
|
/// loads and reads the file asynchonously
|
||||||
/// parses the file line by line to retrieve the credentials
|
/// parses the file line by line to retrieve the credentials
|
||||||
async fn parse_contents(&mut self) {
|
async fn parse_contents(&mut self) {
|
||||||
let contents = tokio::fs::read_to_string(&self.path).await;
|
let contents = tokio::fs::read_to_string(&self.path).await;
|
||||||
@ -54,6 +54,7 @@ impl FileStore {
|
|||||||
self.credentials = credentials;
|
self.credentials = credentials;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// checks if the credentials exist in the `FileStore`
|
||||||
fn auth(&self, username: String, password: String) -> bool {
|
fn auth(&self, username: String, password: String) -> bool {
|
||||||
let credentials: Vec<&Credentials> = self
|
let credentials: Vec<&Credentials> = self
|
||||||
.credentials
|
.credentials
|
||||||
|
|||||||
@ -1,3 +1,9 @@
|
|||||||
|
//! store module lists interfaces available to check request credentials
|
||||||
|
//! each store must implement the trait `is_auth`
|
||||||
|
//! two stores are available :
|
||||||
|
//! * `FileStore`: credentials stored in a text file (like **/etc/passwd**)
|
||||||
|
//! * `DBStore`: credentials stored in a database (TODO)
|
||||||
|
|
||||||
mod file;
|
mod file;
|
||||||
mod store;
|
mod store;
|
||||||
|
|
||||||
|
|||||||
@ -7,7 +7,7 @@ pub trait Store {
|
|||||||
async fn is_auth(&mut self, data: &json::JsonValue) -> bool;
|
async fn is_auth(&mut self, data: &json::JsonValue) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// extract_json_value extracts String json value from a key
|
/// extracts `String` json value from a key
|
||||||
fn extract_json_value(data: &Object, key: &str) -> String {
|
fn extract_json_value(data: &Object, key: &str) -> String {
|
||||||
if let Some(u) = data.get(key) {
|
if let Some(u) = data.get(key) {
|
||||||
match u.as_str() {
|
match u.as_str() {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user