Codice sorgente per server

import json
import os
from http.server import BaseHTTPRequestHandler, HTTPServer
from routes import route_request
from db import init_db
from utility.utility import set_headers
from socketserver import ThreadingMixIn

[documenti] class ThreadingHTTPServer(ThreadingMixIn, HTTPServer): """Server HTTP che supporta il multi-threading.""" # quando il server รจ terminato chiude i thread daemon_threads = True
[documenti] class MyHandler(BaseHTTPRequestHandler): server_version = "CustomHTTPServer" sys_version = "" protocol_version = "HTTP/1.1"
[documenti] def do_OPTIONS(self): """Gestisce le richieste OPTIONS. Utilizzato per la preflight CORS.""" set_headers(self, 200)
[documenti] def do_GET(self): """Gestisce le richieste GET. E inoltre serve file statici del front end.""" # serve/fornisce i file statici dalla cartella 'frontend' if self.path.startswith("/frontend") or self.path == "/" or self.path.endswith( (".html", ".css", ".js", ".png", ".jpg", ".jpeg", ".ico", ".svg")): self.serve_static_file() else: # gestione di richieste API route_request(self, "GET")
[documenti] def serve_static_file(self): """Serve i file statici dalla cartella 'frontend'.""" # costruisce il percorso per recuperare il file richiesto base_path = os.path.join(os.getcwd(), "frontend") requested_path = self.path.lstrip("/") # log per debug print(f"Richiesta file statico: {requested_path}") # restituisce l'index.html di default se viene richiesta la root if not requested_path or requested_path.endswith("/"): requested_path = os.path.join(requested_path, "index.html") # costruisce il percorso completo del file file_path = os.path.join(base_path, requested_path) print(f"Percorso completo: {file_path}") # verifica se il file esiste if os.path.isfile(file_path): try: self._read_and_send_file(file_path) except Exception as e: print(f"Errore durante il caricamento del file statico: {e}") error_response = json.dumps({"error": "Errore interno del server"}).encode("utf-8") set_headers(self, 500, error_response ) self.wfile.write(error_response) else: print(f"File non trovato: {file_path}") error_response = json.dumps({"error": "File non trovato"}).encode("utf-8") set_headers(self, 404, error_response ) # todo: inserire nel metodo set_headers self.wfile.write(***) visto che passo il parametro response_data self.wfile.write(error_response)
def _read_and_send_file(self, file_path): """Serve un singolo file statico.""" with open(file_path, "rb") as f: file_content = f.read() content_type = self._get_content_type(file_path) set_headers(self, 200, file_content,content_type) self.wfile.write(file_content); print(f"File statico servito: {file_path}") def _get_content_type(self, file_path): """restituisce in base all'estensione del file il Content-Type.""" if file_path.endswith(".html"): return "text/html" elif file_path.endswith(".css"): return "text/css" elif file_path.endswith(".js"): return "application/javascript" elif file_path.endswith(".png"): return "image/png" elif file_path.endswith(".jpg") or file_path.endswith(".jpeg"): return "image/jpeg" elif file_path.endswith(".gif"): return "image/gif" elif file_path.endswith(".ico"): return "image/x-icon" return "application/octet-stream"
[documenti] def do_POST(self): """Gestisce le richieste POST.""" route_request(self, "POST")
[documenti] def do_PUT(self): """Gestisce le richieste PUT.""" route_request(self, "PUT")
[documenti] def do_DELETE(self): """Gestisce le richieste DELETE.""" route_request(self, "DELETE")
[documenti] def run_server(port=8000): """Avvia il server multi-threaded.""" init_db() server_address = ("0.0.0.0", port) httpd = ThreadingHTTPServer(server_address, MyHandler) print(f"Server multi-threaded in esecuzione sulla porta {port}...") try: httpd.serve_forever() except KeyboardInterrupt: print("\nRicevuto Ctrl + C: chiusura del server...") finally: httpd.shutdown() httpd.server_close() print("Server terminato correttamente.")
if __name__ == "__main__": run_server()