✨ HTTP implementation
This commit is contained in:
@ -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
|
||||
|
||||
|
@ -89,8 +89,8 @@ def sigfigs(num):
|
||||
|
||||
def main():
|
||||
monitors = 1
|
||||
patterns = 1000
|
||||
events = 1
|
||||
patterns = 1
|
||||
events = 10_000
|
||||
|
||||
n = 100
|
||||
|
||||
|
@ -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}
|
||||
)
|
||||
|
||||
|
Reference in New Issue
Block a user