feat: #2 impl an HTTPResponse + update tests
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
pub mod request;
|
||||
pub mod response;
|
||||
|
||||
pub use request::handle_request;
|
||||
pub use response::HTTPResponse;
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
//! response handles the incoming request parsed `HTTPRequest`
|
||||
//! it will check if the `HTTPRequest` is valid and build an HTTPResponse corresponding to the HTTP
|
||||
//! message specs. see: https://developer.mozilla.org/en-US/docs/Web/HTTP/Messages
|
||||
//! NOTE: only few parts of the specification has been implemented
|
||||
|
||||
use json;
|
||||
|
||||
use crate::handlers::request::{HTTPRequest, HTTPVersion};
|
||||
|
||||
enum HTTPStatusCode {
|
||||
Http200,
|
||||
Http400,
|
||||
Http404,
|
||||
Http500,
|
||||
}
|
||||
|
||||
impl Into<String> for HTTPStatusCode {
|
||||
fn into(self) -> String {
|
||||
match self {
|
||||
Self::Http200 => "200".to_string(),
|
||||
Self::Http400 => "400".to_string(),
|
||||
Self::Http404 => "404".to_string(),
|
||||
Self::Http500 => "500".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct HTTPStatusLine {
|
||||
version: HTTPVersion,
|
||||
status_code: HTTPStatusCode,
|
||||
}
|
||||
|
||||
impl Default for HTTPStatusLine {
|
||||
fn default() -> HTTPStatusLine {
|
||||
HTTPStatusLine {
|
||||
version: HTTPVersion::Http1_1,
|
||||
status_code: HTTPStatusCode::Http400,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<String> for HTTPStatusLine {
|
||||
fn into(self) -> String {
|
||||
let version: String = self.version.into();
|
||||
let status_code: String = self.status_code.into();
|
||||
format! {"{} {}", version, status_code}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct HTTPResponse {
|
||||
status_line: HTTPStatusLine,
|
||||
body: json::JsonValue,
|
||||
}
|
||||
|
||||
impl Default for HTTPResponse {
|
||||
fn default() -> Self {
|
||||
HTTPResponse {
|
||||
status_line: HTTPStatusLine::default(),
|
||||
body: json::parse(r#"{"error": "the incoming request is not valid"}"#).unwrap(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<HTTPRequest> for HTTPResponse {
|
||||
fn from(request: HTTPRequest) -> Self {
|
||||
let mut response = HTTPResponse::default();
|
||||
if !request.is_valid() {
|
||||
return response;
|
||||
}
|
||||
|
||||
let body = json::parse(
|
||||
r#"{"token": "header.payload.signature", "refresh": "header.payload.signature"}"#,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
response.status_line.version = request.start_line.version;
|
||||
response.status_line.status_code = HTTPStatusCode::Http200;
|
||||
response.body = body;
|
||||
|
||||
response
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<String> for HTTPResponse {
|
||||
fn into(self) -> String {
|
||||
// move `self.body` into a new var
|
||||
let b = self.body;
|
||||
let body: String = json::stringify(b);
|
||||
|
||||
let status_line: String = self.status_line.into();
|
||||
format!(
|
||||
"{}\r\nContent-Type: application/json\r\nContent-Length: {}\r\n\r\n{}",
|
||||
status_line,
|
||||
body.len(),
|
||||
body
|
||||
)
|
||||
}
|
||||
}
|
||||
+4
-17
@@ -1,13 +1,11 @@
|
||||
mod handlers;
|
||||
|
||||
use std::io::prelude::*;
|
||||
|
||||
use tokio::{
|
||||
io::{AsyncReadExt, AsyncWriteExt},
|
||||
net::{TcpListener, TcpStream},
|
||||
};
|
||||
|
||||
use handlers::handle_request;
|
||||
use handlers::{handle_request, HTTPResponse};
|
||||
|
||||
const SERVER_URL: &str = "127.0.0.1:9000";
|
||||
|
||||
@@ -29,20 +27,9 @@ async fn handle_connection(mut stream: TcpStream) {
|
||||
let request_string = std::str::from_utf8(&buffer[0..n]).unwrap();
|
||||
let request = handle_request(request_string);
|
||||
|
||||
if request.is_valid() {
|
||||
let contents = "{\"status\": \"ok\"}";
|
||||
let response = format!(
|
||||
"HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nContent-Length: {}\r\n\r\n{}",
|
||||
contents.len(),
|
||||
contents
|
||||
);
|
||||
let response = HTTPResponse::from(request);
|
||||
let response_str: String = response.into();
|
||||
|
||||
stream.write(response.as_bytes()).await.unwrap();
|
||||
stream.flush().await.unwrap();
|
||||
return;
|
||||
}
|
||||
|
||||
let response = "HTTP/1.1 400 OK\r\n\r\n".to_string();
|
||||
stream.write(response.as_bytes()).await.unwrap();
|
||||
stream.write(response_str.as_bytes()).await.unwrap();
|
||||
stream.flush().await.unwrap();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user