rewrite routing logic
This commit is contained in:
parent
451eb99f8a
commit
42191f4e77
89
owrx/http.py
89
owrx/http.py
@ -17,6 +17,7 @@ from owrx.controllers.metrics import MetricsController
|
|||||||
from http.server import BaseHTTPRequestHandler
|
from http.server import BaseHTTPRequestHandler
|
||||||
from urllib.parse import urlparse, parse_qs
|
from urllib.parse import urlparse, parse_qs
|
||||||
import re
|
import re
|
||||||
|
from abc import ABC, abstractmethod
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
@ -37,46 +38,74 @@ class RequestHandler(BaseHTTPRequestHandler):
|
|||||||
|
|
||||||
|
|
||||||
class Request(object):
|
class Request(object):
|
||||||
def __init__(self, query=None, matches=None):
|
def __init__(self, url):
|
||||||
self.query = query
|
self.path = url.path
|
||||||
|
self.query = parse_qs(url.query)
|
||||||
|
self.matches = None
|
||||||
|
|
||||||
|
def setMatches(self, matches):
|
||||||
self.matches = matches
|
self.matches = matches
|
||||||
|
|
||||||
|
|
||||||
|
class Route(ABC):
|
||||||
|
def __init__(self, controller):
|
||||||
|
self.controller = controller
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def matches(self, request):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class StaticRoute(Route):
|
||||||
|
def __init__(self, route, controller):
|
||||||
|
self.route = route
|
||||||
|
super().__init__(controller)
|
||||||
|
|
||||||
|
def matches(self, request):
|
||||||
|
return request.path == self.route
|
||||||
|
|
||||||
|
|
||||||
|
class RegexRoute(Route):
|
||||||
|
def __init__(self, regex, controller):
|
||||||
|
self.regex = re.compile(regex)
|
||||||
|
super().__init__(controller)
|
||||||
|
|
||||||
|
def matches(self, request):
|
||||||
|
matches = self.regex.match(request.path)
|
||||||
|
# this is probably not the cleanest way to do it...
|
||||||
|
request.setMatches(matches)
|
||||||
|
return matches is not None
|
||||||
|
|
||||||
|
|
||||||
class Router(object):
|
class Router(object):
|
||||||
mappings = [
|
def __init__(self):
|
||||||
{"route": "/", "controller": IndexController},
|
self.routes = [
|
||||||
{"route": "/status", "controller": StatusController},
|
StaticRoute("/", IndexController),
|
||||||
{"route": "/status.json", "controller": StatusJsonController},
|
StaticRoute("/status", StatusController),
|
||||||
{"regex": "/static/(.+)", "controller": OwrxAssetsController},
|
StaticRoute("/status.json", StatusJsonController),
|
||||||
{"regex": "/aprs-symbols/(.+)", "controller": AprsSymbolsController},
|
RegexRoute("/static/(.+)", OwrxAssetsController),
|
||||||
{"route": "/ws/", "controller": WebSocketController},
|
RegexRoute("/aprs-symbols/(.+)", AprsSymbolsController),
|
||||||
{"regex": "(/favicon.ico)", "controller": OwrxAssetsController},
|
StaticRoute("/ws/", WebSocketController),
|
||||||
|
RegexRoute("(/favicon.ico)", OwrxAssetsController),
|
||||||
# backwards compatibility for the sdr.hu portal
|
# backwards compatibility for the sdr.hu portal
|
||||||
{"regex": "/(gfx/openwebrx-avatar.png)", "controller": OwrxAssetsController},
|
RegexRoute("(/gfx/openwebrx-avatar.png)", OwrxAssetsController),
|
||||||
{"route": "/map", "controller": MapController},
|
StaticRoute("/map", MapController),
|
||||||
{"route": "/features", "controller": FeatureController},
|
StaticRoute("/features", FeatureController),
|
||||||
{"route": "/api/features", "controller": ApiController},
|
StaticRoute("/api/features", ApiController),
|
||||||
{"route": "/metrics", "controller": MetricsController},
|
StaticRoute("/metrics", MetricsController),
|
||||||
]
|
]
|
||||||
|
|
||||||
def find_controller(self, path):
|
def find_route(self, request):
|
||||||
for m in Router.mappings:
|
for r in self.routes:
|
||||||
if "route" in m:
|
if r.matches(request):
|
||||||
if m["route"] == path:
|
return r
|
||||||
return (m["controller"], None)
|
|
||||||
if "regex" in m:
|
|
||||||
regex = re.compile(m["regex"])
|
|
||||||
matches = regex.match(path)
|
|
||||||
if matches:
|
|
||||||
return (m["controller"], matches)
|
|
||||||
|
|
||||||
def route(self, handler):
|
def route(self, handler):
|
||||||
url = urlparse(handler.path)
|
url = urlparse(handler.path)
|
||||||
res = self.find_controller(url.path)
|
request = Request(url)
|
||||||
if res is not None:
|
route = self.find_route(request)
|
||||||
(controller, matches) = res
|
if route is not None:
|
||||||
query = parse_qs(url.query)
|
controller = route.controller
|
||||||
request = Request(query, matches)
|
|
||||||
controller(handler, request).handle_request()
|
controller(handler, request).handle_request()
|
||||||
else:
|
else:
|
||||||
handler.send_error(404, "Not Found", "The page you requested could not be found.")
|
handler.send_error(404, "Not Found", "The page you requested could not be found.")
|
||||||
|
Loading…
Reference in New Issue
Block a user