feat: new format response in order to properly manage headers
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
# TODO
|
||||
|
||||
- [x] Manage requests
|
||||
- [x] Router
|
||||
- [NOT NEEDED] HTTP code mapper : not needed because a code will be directly translated on the client (browser / postman)
|
||||
@@ -9,7 +10,10 @@
|
||||
- [ ] Auto-cleanup
|
||||
- [ ] Transversal utility
|
||||
- [ ] Let programmer set the default not found response
|
||||
- [x] Manage basic defaults app and route headers
|
||||
- [ ] Manage route specific headers
|
||||
- [ ] Allow middleware
|
||||
- [ ] Study how to organize functions on structs or types if possible
|
||||
|
||||
## Improvements
|
||||
|
||||
|
||||
@@ -1,3 +1,29 @@
|
||||
use super::*;
|
||||
|
||||
// pub fn generate_response(petition: HttpRequest) -> ProcessedResponse {}
|
||||
|
||||
fn format_response_headers(headers: Headers, content_len: usize, content_type: &str) -> String {
|
||||
let mut response_headers = String::new();
|
||||
response_headers.push_str(format!("Content-Length: {}", content_len).as_str());
|
||||
response_headers.push_str(format!("\nContent-Type: {}", content_type).as_str());
|
||||
for (key, value) in headers {
|
||||
response_headers.push_str(format!("\n{key}: {value}").as_str());
|
||||
}
|
||||
return response_headers;
|
||||
}
|
||||
|
||||
pub fn format_response(raw_response: HttpAppRouteResponse) -> ProcessedResponse {
|
||||
ProcessedResponse {
|
||||
data: format!(
|
||||
"HTTP/1.1 {}\r\n{}\r\n\r\n{}",
|
||||
raw_response.status,
|
||||
format_response_headers(
|
||||
raw_response.headers,
|
||||
raw_response.body.len(),
|
||||
raw_response.content_type
|
||||
),
|
||||
raw_response.body
|
||||
),
|
||||
status: raw_response.status,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,29 @@
|
||||
use std::fs;
|
||||
use std::collections::HashMap;
|
||||
use std::io::prelude::*;
|
||||
use std::net::{SocketAddr, TcpListener, TcpStream};
|
||||
|
||||
use super::*;
|
||||
|
||||
impl HttpApp {
|
||||
impl Default for HttpAppConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
port: 3000,
|
||||
max_buffer_size_bytes: 5120,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for HttpApp<'_> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
config: Default::default(),
|
||||
routes: vec![],
|
||||
default_headers: HashMap::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl HttpApp<'_> {
|
||||
fn get_route(&self, _path: &str) -> Option<&HttpAppRoute> {
|
||||
self.routes.first() // TODO: search the real one
|
||||
}
|
||||
@@ -21,37 +40,22 @@ impl HttpApp {
|
||||
|
||||
match petition {
|
||||
Ok(petition_parsed) => {
|
||||
let response_status = "200 OK";
|
||||
|
||||
// let mut response_content = fs::read_to_string("./routes/index.html").unwrap();
|
||||
let mut response_content = "".to_string();
|
||||
|
||||
if let Some(route) = self.get_route(petition_parsed.request.query.path) {
|
||||
response_content = (route.action)(petition_parsed);
|
||||
let matched_route = (route.action)(petition_parsed);
|
||||
return format_response(matched_route);
|
||||
} else {
|
||||
// TODO: return not found
|
||||
return ProcessedResponse {
|
||||
data: "".to_string(),
|
||||
status: 400,
|
||||
};
|
||||
}
|
||||
|
||||
let response: ProcessedResponse = ProcessedResponse {
|
||||
data: format!(
|
||||
"HTTP/1.1 {}\r\nContent-Length: {}\r\n\r\n{}",
|
||||
response_status,
|
||||
response_content.len(),
|
||||
response_content
|
||||
),
|
||||
status: 200,
|
||||
};
|
||||
|
||||
response
|
||||
}
|
||||
Err(error) => {
|
||||
let response: ProcessedResponse = ProcessedResponse {
|
||||
data: format!("HTTP/1.1 {}\r\nContent-Length: 0\r\n\r\n", error),
|
||||
status: error,
|
||||
};
|
||||
|
||||
response
|
||||
}
|
||||
Err(error) => ProcessedResponse {
|
||||
data: format!("HTTP/1.1 {}\r\nContent-Length: 0\r\n\r\n", error),
|
||||
status: error,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,18 +5,27 @@ use std::collections::HashMap;
|
||||
* */
|
||||
pub struct HttpAppConfig {
|
||||
pub port: u16,
|
||||
pub max_buffer_size_bytes: usize,
|
||||
}
|
||||
|
||||
pub type HttpAppRouteFunction = Box<fn(HttpRequest) -> String>;
|
||||
pub type HttpAppRouteFunction = Box<fn(HttpRequest) -> HttpAppRouteResponse>;
|
||||
|
||||
pub struct HttpAppRoute {
|
||||
pub route: String,
|
||||
pub action: HttpAppRouteFunction,
|
||||
}
|
||||
|
||||
pub struct HttpApp {
|
||||
pub struct HttpApp<'a> {
|
||||
pub config: HttpAppConfig,
|
||||
pub routes: Vec<HttpAppRoute>,
|
||||
pub default_headers: Headers<'a>,
|
||||
}
|
||||
|
||||
pub struct HttpAppRouteResponse<'a> {
|
||||
pub body: String,
|
||||
pub content_type: &'a str,
|
||||
pub status: Status,
|
||||
pub headers: Headers<'a>,
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user