#!/usr/bin/env python3 # -*- coding: utf-8 -*- from typing import Any, Optional, Self, Sequence from Interfaces.Application.AnPInterface import AnPInterface from Abstracts.ModelAbstract import ModelAbstract from Models.RequestModel import RequestModel from threading import Thread from http.server import BaseHTTPRequestHandler, HTTPServer from http.cookies import SimpleCookie from Abstracts.HTTPServersAbstract import HTTPServersAbstract class HTTPServerDriver(HTTPServersAbstract, ModelAbstract): class HTTPRequestHandler(BaseHTTPRequestHandler): def __process(self:Self, method:str) -> None: anp:AnPInterface = self.server.anp server:HTTPServersAbstract = self.server.itself request:RequestModel = RequestModel() session_id:str|None = None cookies:SimpleCookie|None = None request.method = method request.path = self.path.split("?")[0] request.headers = dict(self.headers) request.client_host = self.client_address[0] request.client_port = self.client_address[1] request.get_variables = server.get_variables_from(self.path[self.path.find("?") + 1:] if "?" in self.path else None) request.post_variables = server.get_variables_from(self.rfile.read(int(self.headers.get("Content-Length", 0)))) request.cookies = server.load_cookies(self.headers.get("Cookie")) session_id = request.get("session") request.session = anp.sessions._get_instance(session_id) if session_id is None or request.session is None: cookies = SimpleCookie() session_id = anp.sessions.create() cookies["session"] = session_id cookies["session"]["path"] = "/" cookies["session"]["max-age"] = server._session_timeout # cookies["session"]["HttpOnly"] = True # cookies["session"]["Secure"] = True request.session = anp.sessions._get_instance(session_id) anp.routes.go([self.server.key], method, self.path, request) self.send_response(request.response_code) self.send_header("Content-Type", request.response_mime) self.send_header("Content-Length", str(len(request.response))) if cookies is not None: morsel:str for morsel in cookies.values(): self.send_header("Set-Cookie", morsel.OutputString()) self.end_headers() self.wfile.write( request.response.encode() if isinstance(request.response, str) else request.response) def do_GET(self:Self) -> None: self.__process("get") def do_POST(self:Self) -> None: self.__process("post") def do_PUT(self:Self) -> None: self.__process("put") def do_DELETE(self:Self) -> None: self.__process("delete") def do_PATCH(self:Self) -> None: self.__process("patch") def do_HEAD(self:Self) -> None: self.__process("head") def do_OPTIONS(self:Self) -> None: self.__process("options") def do_CONNECT(self:Self) -> None: self.__process("connect") def do_TRACE(self:Self) -> None: self.__process("trace") def do_COPY(self:Self) -> None: self.__process("copy") def do_MOVE(self:Self) -> None: self.__process("move") def do_PROPFIND(self:Self) -> None: self.__process("propfind") def do_PROPPATCH(self:Self) -> None: self.__process("proppatch") def do_LOCK(self:Self) -> None: self.__process("lock") def do_UNLOCK(self:Self) -> None: self.__process("unlock") def do_REPORT(self:Self) -> None: self.__process("report") def do_MKCOL(self:Self) -> None: self.__process("mkcol") def __init__(self:Self, anp:AnPInterface, key:str, inputs:Optional[dict[str, Any|None]|Sequence[Any|None]] = None ) -> None: self.__server:HTTPServer|None = None self.__thread:Thread|None = None super().__init__(anp, key, inputs) self.update() anp.settings.get(("http_server_autostart", "autostart"), inputs, True) and self.start() def start(self:Self) -> None: if self.__server is None: self.__thread = Thread(target = self.__run_service) self.__thread.start() def close(self:Self) -> None: if self.__server is not None: self.__server.shutdown() self.__server = None def __run_service(self:Self) -> None: self.__server = HTTPServer((self.host, self.port), self.HTTPRequestHandler) self.__server.anp = self.anp self.__server.itself = self self.__server.key = self.key self.__server.serve_forever()