Verteiltesystheme/Code/Communication/RequestHandler.py

92 lines
2.8 KiB
Python

import json
import re
import urllib.parse
from dataclasses import asdict
from http.server import BaseHTTPRequestHandler
from Code.Communication.Direction import Direction
from Code.Communication.Neighbours import Neighbours
from Code.UI.PlayingField import GameState
class RequestHandler(BaseHTTPRequestHandler):
neighbours: Neighbours = None
game_state: GameState = None
def do_GET(self):
print("got Get request")
if self.path == "/":
self.send_response(200, "running")
self.end_headers()
return
elif self.path.startswith("/border/"):
direction = re.findall("/border/(left|right).*", self.path, flags=re.IGNORECASE)[0]
params = urllib.parse.parse_qs(self.path)
counter = int(params[list(params.keys())[0]][0])
print(f"Getting {direction} edge for counter {counter}")
cells = self.game_state.edge_sync.get_edge(Direction[direction.upper()], counter)
print(f"Serving {direction} edge")
self.send_response(200)
self.send_header('Content-Type', 'application/json')
self.end_headers()
self.wfile.write(json.dumps(cells).encode('utf8'))
return
else:
self.send_response(404)
self.end_headers()
return
def do_POST(self):
"""
/connect/right
/connect/left
with body : {ip:"string",port:number}
"""
if self.path.startswith("/connect/"):
direction = re.findall("/connect/(left|right)", self.path, flags=re.IGNORECASE)[0]
data_string = self.rfile.read(int(self.headers['Content-Length']))
print(f"Got connection request with value {data_string}")
data = json.loads(data_string)
neighbour, accepted = self.neighbours.accept_connection(Direction[direction.upper()],
data["ip"],
data["port"])
print(f"Sending neighbour: {neighbour}")
if accepted:
self.send_response(200)
self.send_header('Content-Type', 'application/json')
self.end_headers()
body = asdict(neighbour)
body["counter"]= self.game_state.counter
self.wfile.write(json.dumps(body).encode('utf8'))
return
else:
self.send_response(307)
self.send_header('Location', f"http://{neighbour.ip}:{neighbour.port}{self.path}")
self.end_headers()
return
elif self.path.startswith("/pause/"):
new_state = re.findall("/pause/(stop|start)", self.path, flags=re.IGNORECASE)[0] == "start"
print(f"pause endpoint {new_state} old state {self.game_state.is_evolving}")
if new_state == self.game_state.is_evolving:
print("got pause signal but already in the correct state")
self.send_response(200)
self.end_headers()
return
else:
self.send_response(200)
self.game_state.is_evolving = new_state
self.neighbours.toggle_pause(new_state)
self.end_headers()
return
else:
self.send_response(404)
self.end_headers()
return