improve HTTPResponse to include custom HTTPMessage
This commit is contained in:
parent
808cd3ee77
commit
7073a4b88e
@ -33,10 +33,27 @@ impl TryInto<json::JsonValue> for HTTPMessage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl HTTPMessage {
|
impl HTTPMessage {
|
||||||
fn put(&mut self, key: &str, value: &str) {
|
pub fn put(&mut self, key: &str, value: &str) {
|
||||||
self.message.insert(key.to_string(), value.to_string());
|
self.message.insert(key.to_string(), value.to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// associated function to build an HTTPMessage error
|
||||||
|
pub fn error(message: &str) -> Option<json::JsonValue> {
|
||||||
|
let mut http_message = HTTPMessage::default();
|
||||||
|
http_message.put("error", message);
|
||||||
|
|
||||||
|
match message.try_into() {
|
||||||
|
Ok(m) => Some(m),
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!(
|
||||||
|
"unable to parse the message: {} into JSON, err={}",
|
||||||
|
message, e
|
||||||
|
);
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// loops over all the HashMap keys, builds a JSON key value for each one and join them with `JSON_DELIMITER`
|
/// loops over all the HashMap keys, builds a JSON key value for each one and join them with `JSON_DELIMITER`
|
||||||
fn build_json(self) -> String {
|
fn build_json(self) -> String {
|
||||||
let unstruct: Vec<String> = self
|
let unstruct: Vec<String> = self
|
||||||
|
|||||||
@ -6,6 +6,6 @@ pub mod response;
|
|||||||
pub mod router;
|
pub mod router;
|
||||||
|
|
||||||
pub use message::HTTPMessage;
|
pub use message::HTTPMessage;
|
||||||
pub use request::HTTPRequest;
|
pub use request::{HTTPRequest, HTTPVersion};
|
||||||
pub use response::{HTTPResponse, HTTPStatusCode};
|
pub use response::{HTTPResponse, HTTPStatusCode};
|
||||||
pub use router::ROUTER;
|
pub use router::ROUTER;
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
//! it will build an HTTPResponse corresponding to the HTTP message specs. see: https://developer.mozilla.org/en-US/docs/Web/HTTP/Messages
|
//! it will 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
|
//! NOTE: only few parts of the specification has been implemented
|
||||||
|
|
||||||
use crate::http::request::HTTPVersion;
|
use super::{HTTPMessage, HTTPVersion};
|
||||||
use json;
|
use json;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
@ -92,13 +92,19 @@ impl Into<String> for HTTPResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl HTTPResponse {
|
impl HTTPResponse {
|
||||||
pub fn as_500() -> Self {
|
pub fn as_500(message: Option<json::JsonValue>) -> Self {
|
||||||
let mut response = Self::default();
|
let mut response = Self::default();
|
||||||
|
|
||||||
response
|
response
|
||||||
.status_line
|
.status_line
|
||||||
.set_status_code(HTTPStatusCode::Http500);
|
.set_status_code(HTTPStatusCode::Http500);
|
||||||
response.body = json::parse(r#"{"error": "unexpected error occurred"}"#).unwrap();
|
|
||||||
|
response.body = {
|
||||||
|
match message {
|
||||||
|
Some(m) => m,
|
||||||
|
None => json::parse(r#"{"error": "unexpected error occurred"}"#).unwrap(),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
response
|
response
|
||||||
}
|
}
|
||||||
@ -119,9 +125,11 @@ impl HTTPResponse {
|
|||||||
status_line: HTTPStatusLine::default(),
|
status_line: HTTPStatusLine::default(),
|
||||||
body: json::parse(r#"{"error": "invalid credentials"}"#).unwrap(),
|
body: json::parse(r#"{"error": "invalid credentials"}"#).unwrap(),
|
||||||
};
|
};
|
||||||
|
|
||||||
response
|
response
|
||||||
.status_line
|
.status_line
|
||||||
.set_status_code(HTTPStatusCode::Http403);
|
.set_status_code(HTTPStatusCode::Http403);
|
||||||
|
|
||||||
response
|
response
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,16 +138,35 @@ impl HTTPResponse {
|
|||||||
Self::default()
|
Self::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: need to be adjust to accept `json::JsonValue`
|
pub fn as_200(message: Option<json::JsonValue>) -> Self {
|
||||||
pub fn as_200(token: String) -> Self {
|
|
||||||
let mut response = Self::default();
|
let mut response = Self::default();
|
||||||
|
|
||||||
response
|
response
|
||||||
.status_line
|
.status_line
|
||||||
.set_status_code(HTTPStatusCode::Http200);
|
.set_status_code(HTTPStatusCode::Http200);
|
||||||
|
|
||||||
response.body = json::parse(format!(r#"{{"token": "{}"}}"#, token).as_str()).unwrap();
|
response.body = {
|
||||||
|
match message {
|
||||||
|
Some(m) => m,
|
||||||
|
None => json::parse(r#"{"status": "ok"}"#).unwrap(),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
response
|
response
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// build and HTTP 200 response with the generated JWT
|
||||||
|
pub fn send_token(token: &str) -> Self {
|
||||||
|
let mut http_message = HTTPMessage::default();
|
||||||
|
http_message.put("token", token);
|
||||||
|
|
||||||
|
let message = {
|
||||||
|
match http_message.try_into() {
|
||||||
|
Ok(m) => m,
|
||||||
|
Err(_e) => json::parse(r#"{"token": "error.generation.token"}"#).unwrap(),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
HTTPResponse::as_200(Some(message))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
//! router aims to handle correctly the request corresponding to the target
|
//! router aims to handle correctly the request corresponding to the target
|
||||||
//! it implements all the logic to build an `HTTPResponse`
|
//! it implements all the logic to build an `HTTPResponse`
|
||||||
|
|
||||||
use super::{HTTPRequest, HTTPResponse};
|
use super::{HTTPMessage, HTTPRequest, HTTPResponse};
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::stores::FileStore;
|
use crate::stores::FileStore;
|
||||||
use crate::stores::Store;
|
use crate::stores::Store;
|
||||||
@ -36,10 +36,11 @@ fn handle_get(request: HTTPRequest, config: Config) -> FuturePinned<HTTPResponse
|
|||||||
let jwt_key = {
|
let jwt_key = {
|
||||||
match RS384KeyPair::from_pem(priv_key_content.as_str()) {
|
match RS384KeyPair::from_pem(priv_key_content.as_str()) {
|
||||||
Ok(k) => k,
|
Ok(k) => k,
|
||||||
// TODO: set error in the message body
|
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
eprintln!("error occurred while getting private key err={}", e);
|
let message: Option<json::JsonValue> = HTTPMessage::error(
|
||||||
return HTTPResponse::as_500();
|
format!("unable to load the private key, err={}", e).as_str(),
|
||||||
|
);
|
||||||
|
return HTTPResponse::as_500(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -47,11 +48,12 @@ fn handle_get(request: HTTPRequest, config: Config) -> FuturePinned<HTTPResponse
|
|||||||
claims.issuer = Some(config.jwt_issuer);
|
claims.issuer = Some(config.jwt_issuer);
|
||||||
|
|
||||||
match jwt_key.sign(claims) {
|
match jwt_key.sign(claims) {
|
||||||
Ok(token) => HTTPResponse::as_200(token),
|
Ok(token) => HTTPResponse::send_token(&token),
|
||||||
// TODO: set the error in the message body
|
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
eprintln!("error occurred while signing the token err={}", e);
|
let message: Option<json::JsonValue> = HTTPMessage::error(
|
||||||
return HTTPResponse::as_500();
|
format!("unable to sign the token, err={}", e).as_str(),
|
||||||
|
);
|
||||||
|
return HTTPResponse::as_500(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -67,7 +69,7 @@ fn handle_validate(request: HTTPRequest, _config: Config) -> FuturePinned<HTTPRe
|
|||||||
match &request.body {
|
match &request.body {
|
||||||
Some(ref _b) => {
|
Some(ref _b) => {
|
||||||
// TODO: impl the JWT validation
|
// TODO: impl the JWT validation
|
||||||
HTTPResponse::as_200("header.payload.signature".to_string())
|
HTTPResponse::send_token("header.payload.signature")
|
||||||
}
|
}
|
||||||
None => HTTPResponse::as_400(),
|
None => HTTPResponse::as_400(),
|
||||||
}
|
}
|
||||||
|
|||||||
@ -46,10 +46,13 @@ async fn main() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let router_config: Config = if let Ok(c) = Config::try_from(config) {
|
let router_config: Config = {
|
||||||
c
|
match Config::try_from(config) {
|
||||||
} else {
|
Ok(c) => c,
|
||||||
|
Err(_e) => {
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user