#!/usr/bin/env python3 # -*- coding: utf-8 -*- from typing import Self, Any, Optional, Sequence from re import Match as REMatch from Utils.Utils import Utils from Utils.Patterns import RE class RequestModel: def __init__(self:Self, data:bytes, index_files:tuple[str, ...], encoder:str = "utf-8") -> None: self.method:str self.request:str self.value_get:str|None self.variables_get:dict[str, str] self.variables_post:dict[str, str] self.protocol:str self.protocol_version:str self.body:str self.variables_uri:dict[str, str] = {} self.index_files:tuple[str, ...] = index_files header, body = (lambda header, body:( RE.NEW_LINE.split(str(header).strip()), body ))(*RE.HTTP_BLOCKS.match(data.decode(encoder)).groups()) ( self.method, self.request, self.value_get, self.variables_get, self.protocol, self.protocol_version ) = (lambda method, request, variables, protocol, protocol_version:( str(method).lower(), request, variables, self.parse_variables(variables), protocol, protocol_version ))(*RE.HTTP_REQUEST.match(header[0]).groups()) self.body = body self.variables_post = self.parse_variables(body) def set_uri_variables(self:Self, keys:list[str], matches:REMatch) -> None: i:int value:str for i, value in enumerate(matches.groups()): self.variables_uri[keys[i]] = value def get(self:Self, keys:str|Sequence[str], default:Optional[Any] = None) -> Any|None: return Utils.get_value(keys, ( self.variables_uri, self.variables_get, self.variables_post ), default) @classmethod def parse_variables(cls:type[Self], string:Optional[str]) -> dict[str, str]: if not string: return {} variables:dict[str, str] = {} pair:str for pair in string.split("&"): if "=" in pair: key, value = pair.split("=", 1) variables[Utils.to_snake(key)] = value else: variables[Utils.to_snake(pair)] = "" return variables