feat: new format response in order to properly manage headers

This commit is contained in:
2025-01-16 20:42:46 +01:00
parent 3160febb58
commit 73a2748806
4 changed files with 72 additions and 29 deletions

View File

@@ -1,4 +1,5 @@
# TODO # TODO
- [x] Manage requests - [x] Manage requests
- [x] Router - [x] Router
- [NOT NEEDED] HTTP code mapper : not needed because a code will be directly translated on the client (browser / postman) - [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 - [ ] Auto-cleanup
- [ ] Transversal utility - [ ] Transversal utility
- [ ] Let programmer set the default not found response - [ ] Let programmer set the default not found response
- [x] Manage basic defaults app and route headers
- [ ] Manage route specific headers
- [ ] Allow middleware - [ ] Allow middleware
- [ ] Study how to organize functions on structs or types if possible
## Improvements ## Improvements

View File

@@ -1,3 +1,29 @@
use super::*; use super::*;
// pub fn generate_response(petition: HttpRequest) -> ProcessedResponse {} // 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,
}
}

View File

@@ -1,10 +1,29 @@
use std::fs; use std::collections::HashMap;
use std::io::prelude::*; use std::io::prelude::*;
use std::net::{SocketAddr, TcpListener, TcpStream}; use std::net::{SocketAddr, TcpListener, TcpStream};
use super::*; 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> { fn get_route(&self, _path: &str) -> Option<&HttpAppRoute> {
self.routes.first() // TODO: search the real one self.routes.first() // TODO: search the real one
} }
@@ -21,37 +40,22 @@ impl HttpApp {
match petition { match petition {
Ok(petition_parsed) => { Ok(petition_parsed) => {
let response_status = "200 OK";
// let mut response_content = fs::read_to_string("./routes/index.html").unwrap(); // 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) { 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 { } else {
// TODO: return not found // TODO: return not found
} return ProcessedResponse {
data: "".to_string(),
let response: ProcessedResponse = ProcessedResponse { status: 400,
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 { Err(error) => ProcessedResponse {
data: format!("HTTP/1.1 {}\r\nContent-Length: 0\r\n\r\n", error), data: format!("HTTP/1.1 {}\r\nContent-Length: 0\r\n\r\n", error),
status: error, status: error,
}; },
response
}
} }
} }

View File

@@ -5,18 +5,27 @@ use std::collections::HashMap;
* */ * */
pub struct HttpAppConfig { pub struct HttpAppConfig {
pub port: u16, 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 struct HttpAppRoute {
pub route: String, pub route: String,
pub action: HttpAppRouteFunction, pub action: HttpAppRouteFunction,
} }
pub struct HttpApp { pub struct HttpApp<'a> {
pub config: HttpAppConfig, pub config: HttpAppConfig,
pub routes: Vec<HttpAppRoute>, 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>,
} }
/* /*