This commit is contained in:
Victor Vobis 2025-09-10 17:45:09 +02:00
parent 46c9ac3dd7
commit 7dd25c1580
5 changed files with 93 additions and 70 deletions

View File

@ -3,52 +3,85 @@ use thiserror::Error;
use crate::{ log, PROJECT_PATH };
use vlogger::*;
use std::fs;
#[derive(Error, Debug)]
pub enum HttpServerError {
#[error("Socket Error: {0}")]
SockerError(#[from] std::io::Error)
}
const ENDPOINTS: [&str; 3] = ["/index.html", "/app.js", "/404.html"];
const INTERNAL_SERVER_ERROR: &'static str = r#"
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Node</title>
<link href="css/style.css" rel="stylesheet">
</head>
<body>
<h1>500 - Internal Server Error</h1>
<p>{}</p>
</body>
</html>
"#;
fn derive_content_type(endpoint: &String) -> &str {
match endpoint.rsplit(".").last() {
fn derive_content_type(endpoint: &str) -> &'static str {
match endpoint.rsplit(".").next() {
Some(ext) => {
log(msg!(DEBUG, "{:?}", ext));
match ext {
"html" => "text/html",
"js" => "text/javascript",
"css" => "text/css",
_ => "text/plain"
}
}
None => {
"text/plain"
"text/json"
}
}
}
fn file_response(path: String, endpoint: String) -> Result<Response<std::fs::File>, std::io::Error> {
let file = std::fs::OpenOptions::new().read(true).open(path)?;
let content_type = derive_content_type(&endpoint);
Ok(
Response::from_file(file)
.with_status_code(200)
.with_header(Header::from_bytes(&b"Content-Type"[..], content_type.as_bytes()).unwrap())
)
fn serve_static(status: u16, file_path: &'static str) -> Result<Response<fs::File>, HttpServerError> {
let path: std::path::PathBuf = {PROJECT_PATH.to_string() + "/static" + file_path}.into();
let file = std::fs::File::open(path)?;
let content_type = derive_content_type(file_path);
let response = Response::from_file(file).with_header(Header::from_bytes(b"Content-Type", content_type.as_bytes()).unwrap()).with_status_code(status);
Ok(response)
}
pub fn start_server() -> Result<(), HttpServerError>{
fn internal_server_error(e: String) -> Response<std::io::Cursor<Vec<u8>>> {
Response::from_string(INTERNAL_SERVER_ERROR.replace("{}", &e))
.with_header(Header::from_bytes(b"Content-Type", b"text/html").unwrap())
}
pub async fn start_server() -> Result<(), HttpServerError>{
let address = "127.0.0.1:6080";
let server = tiny_http::Server::http(address).unwrap();
let root = format!("{}/{}", PROJECT_PATH, "static");
loop {
let req = server.recv()?;
log(msg!(DEBUG, "{:?}", req));
match req.method() {
Method::Get => {
}
_ => {}
let req = server.try_recv()?;
match req {
Some(req) => {
let url = req.url().split('?').next().unwrap();
log(msg!(DEBUG, "{:?}", req.url()));
let response = match (req.method(), url) {
(&Method::Get, "/") => serve_static(200, "/index.html"),
(&Method::Get, "/app.js") => serve_static(200, "/app.js"),
(&Method::Get, "/style.css") => serve_static(200, "/style.css"),
(_, _) => serve_static(404, "/404.html"),
};
match response {
Ok(r) => { let _ = req.respond(r); },
Err(e) => { internal_server_error(e.to_string()); },
};
},
None => {}
}
tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
}
}

View File

@ -473,8 +473,8 @@ impl Node {
.await;
};
tokio::spawn(async move {
let _ = crate::api::server::start_server();
let handle = tokio::spawn(async move {
let _ = crate::api::server::start_server().await;
});
let mut system_rx = subscribe_system_event();
@ -500,6 +500,7 @@ impl Node {
}
}
}
handle.abort_handle().abort();
self.shutdown().await;
}
}

View File

@ -1,5 +1,7 @@
const API_URL='http://localhost:6080/api/';
console.log("Hello World");
const connection = {
ws: [],
node_list: [],
@ -14,7 +16,7 @@ function updateTableStats() {
}
async function getTableContent() {
let response = await fetch(API_URL + "get_table");
let response = await fetch(API_URL + "get_table_content");
let content = await response.json()
console.log(content);

View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title></title>
<!-- <link href="css/style.css" rel="stylesheet"> -->
<link href="style.css" rel="stylesheet">
</head>
<body class="background">
<div class="main-container">
@ -21,52 +21,7 @@
</div>
</div>
<script src="/app.js" ></script>
<script>
await getTableContent();
const table = document.getElementById('stat-table-body');
for (var i = 0; i < 30; i++)
{
const new_row = document.createElement('tr');
let row_content = '';
for (var j = 0; j < 5; j++) {
row_content += `<td style="text-align: right; padding: 0 4px ; border-top: 1px solid black;">${i + j}</td>`
}
new_row.innerHTML = row_content;
table.appendChild(new_row);
}
</script>
</body>
<style>
body {
margin: 0;
padding: 0;
}
.main-container {
padding: 6px;
display: flex;
align-content: center;
flex-direction: column;
height: 100%;
width: 100%;
box-sizing: border-box;
}
.table-container {
padding: 6px;
place-self: center;
border: 2px solid #000000;
width: 50%;
height: 50%;
box-sizing: border-box;
}
.background {
background-color: #808080;
width: 100vw;
height: 100vh;
max-height: 100vh;
max-width: 100vw;
box-sizing: border-box;
}
</style>
</html>

View File

@ -0,0 +1,32 @@
body {
margin: 0;
padding: 0;
}
.main-container {
padding: 6px;
display: flex;
align-content: center;
flex-direction: column;
height: 100%;
width: 100%;
box-sizing: border-box;
}
.table-container {
padding: 6px;
place-self: center;
border: 2px solid #000000;
width: 50%;
height: 50%;
box-sizing: border-box;
}
.background {
background-color: #808080;
width: 100vw;
height: 100vh;
max-height: 100vh;
max-width: 100vw;
box-sizing: border-box;
}