From 904471004d3d0323332b7d2263190a23d820f687 Mon Sep 17 00:00:00 2001 From: NikolajDanger Date: Sun, 18 Jun 2023 13:17:40 +0200 Subject: [PATCH] :sparkles: HTTP implementation --- patterns/network_event_pattern.py | 51 ++++++++++++++++++++++++++-- performance_test/performance_test.py | 4 +-- tests/test_patterns.py | 3 +- 3 files changed, 52 insertions(+), 6 deletions(-) diff --git a/patterns/network_event_pattern.py b/patterns/network_event_pattern.py index 5e4567a..43150ea 100644 --- a/patterns/network_event_pattern.py +++ b/patterns/network_event_pattern.py @@ -4,10 +4,13 @@ import threading import tempfile import hashlib from os import unlink +from http.server import HTTPServer from time import time from typing import Any, Dict, List +from core.base_recipe import BaseRecipe +from http_parser.parser import HttpParser from meow_base.functionality.validation import valid_string, valid_dict from meow_base.core.vars import VALID_RECIPE_NAME_CHARS, VALID_VARIABLE_NAME_CHARS, DEBUG_INFO @@ -25,6 +28,8 @@ TRIGGERING_PORT = "triggering_port" NETWORK_EVENT_KEYS = { TRIGGERING_PORT: int, + WATCHDOG_HASH: str, + WATCHDOG_BASE: str, **EVENT_KEYS } @@ -91,6 +96,8 @@ class NetworkMonitor(BaseMonitor): self._print_target, self.debug_level = setup_debugging(print, logging) self.ports = set() self.listeners = [] + if not hasattr(self, "listener_type"): + self.listener_type = Listener if autostart: self.start() @@ -104,7 +111,9 @@ class NetworkMonitor(BaseMonitor): self.ports = set( rule.pattern.triggering_port for rule in self._rules.values() ) - self.listeners = [Listener("127.0.0.1",i,2048,self) for i in self.ports] + self.listeners = [ + self.listener_type("127.0.0.1",i,2048,self) for i in self.ports + ] for listener in self.listeners: listener.start() @@ -200,8 +209,7 @@ class Listener(): self.socket.close() - - def handle_event(self, conn, time_stamp): + def receive_data(self,conn): with conn: with tempfile.NamedTemporaryFile("wb", delete=False) as tmp: while True: @@ -212,6 +220,11 @@ class Listener(): tmp_name = tmp.name + return tmp_name + + def handle_event(self, conn, time_stamp): + tmp_name = self.receive_data(conn) + with open(tmp_name, "rb") as file_pointer: file_hash = hashlib.sha256(file_pointer.read()).hexdigest() @@ -225,3 +238,35 @@ class Listener(): def stop(self): self._stopped = True + +class HTTPMonitor(NetworkMonitor): + def __init__(self, patterns: Dict[str, NetworkEventPattern], + recipes: Dict[str, BaseRecipe], autostart=False, + name: str = "", print: Any = sys.stdout, logging: int = 0) -> None: + self.listener_type = HTTPListener() + super().__init__(patterns, recipes, autostart, name, print, logging) + +class HTTPListener(Listener): + def receive_data(self,conn): + parser = HttpParser() + + with conn: + with tempfile.NamedTemporaryFile("wb", delete=False) as tmp: + while True: + data = conn.recv(self.buff_size) + if not data: + break + + received = len(data) + parsed = parser.execute(data, received) + assert parsed == received + + if parser.is_partial_body(): + tmp.write(parser.recv_body()) + + if parser.is_message_complete(): + break + tmp_name = tmp.name + + return tmp_name + diff --git a/performance_test/performance_test.py b/performance_test/performance_test.py index cceb03a..9cf68f9 100644 --- a/performance_test/performance_test.py +++ b/performance_test/performance_test.py @@ -89,8 +89,8 @@ def sigfigs(num): def main(): monitors = 1 - patterns = 1000 - events = 1 + patterns = 1 + events = 10_000 n = 100 diff --git a/tests/test_patterns.py b/tests/test_patterns.py index 309a3c5..69ac4d6 100644 --- a/tests/test_patterns.py +++ b/tests/test_patterns.py @@ -1117,7 +1117,7 @@ class NetworkMonitorTests(unittest.TestCase): with self.assertRaises(TypeError): event = create_network_event("path", rule) - event = create_network_event("path", rule, time(), 8181) + event = create_network_event("path", rule, time(), 8181, "hash") self.assertEqual(type(event), dict) self.assertEqual(len(event.keys()), len(NETWORK_EVENT_KEYS)) @@ -1134,6 +1134,7 @@ class NetworkMonitorTests(unittest.TestCase): rule, time(), 8182, + "hash", extras={"a":1} )