2020-02-23 17:32:37 +00:00
|
|
|
from owrx.controllers.status import StatusController
|
2021-01-20 16:01:46 +00:00
|
|
|
from owrx.controllers.template import IndexController, MapController, FeatureController
|
|
|
|
from owrx.controllers.assets import OwrxAssetsController, AprsSymbolsController, CompiledAssetsController
|
2020-02-23 16:22:13 +00:00
|
|
|
from owrx.controllers.websocket import WebSocketController
|
|
|
|
from owrx.controllers.api import ApiController
|
|
|
|
from owrx.controllers.metrics import MetricsController
|
2021-02-15 14:29:02 +00:00
|
|
|
from owrx.controllers.settings import SettingsController
|
|
|
|
from owrx.controllers.settings.general import GeneralSettingsController
|
|
|
|
from owrx.controllers.settings.sdr import SdrSettingsController
|
2021-02-15 14:49:44 +00:00
|
|
|
from owrx.controllers.settings.reporting import ReportingController
|
2021-02-15 14:56:17 +00:00
|
|
|
from owrx.controllers.settings.backgrounddecoding import BackgroundDecodingController
|
2021-02-15 15:06:14 +00:00
|
|
|
from owrx.controllers.settings.decoding import DecodingSettingsController
|
2021-02-13 16:08:56 +00:00
|
|
|
from owrx.controllers.bookmarks import BookmarksController
|
2020-02-23 18:23:18 +00:00
|
|
|
from owrx.controllers.session import SessionController
|
2021-02-08 17:30:54 +00:00
|
|
|
from owrx.controllers.profile import ProfileController
|
2021-02-08 22:29:24 +00:00
|
|
|
from owrx.controllers.imageupload import ImageUploadController
|
2019-05-03 20:59:24 +00:00
|
|
|
from http.server import BaseHTTPRequestHandler
|
2019-07-06 11:03:49 +00:00
|
|
|
from urllib.parse import urlparse, parse_qs
|
2019-09-21 11:49:37 +00:00
|
|
|
import re
|
2020-02-23 16:53:02 +00:00
|
|
|
from abc import ABC, abstractmethod
|
2020-02-23 20:52:13 +00:00
|
|
|
from http.cookies import SimpleCookie
|
2019-05-03 20:59:24 +00:00
|
|
|
|
2019-05-10 19:50:58 +00:00
|
|
|
import logging
|
2019-07-21 17:40:28 +00:00
|
|
|
|
2019-05-10 19:50:58 +00:00
|
|
|
logger = logging.getLogger(__name__)
|
2019-09-22 18:51:33 +00:00
|
|
|
logger.setLevel(logging.INFO)
|
2019-05-10 19:50:58 +00:00
|
|
|
|
2019-07-21 17:40:28 +00:00
|
|
|
|
2019-05-03 20:59:24 +00:00
|
|
|
class RequestHandler(BaseHTTPRequestHandler):
|
|
|
|
def __init__(self, request, client_address, server):
|
|
|
|
self.router = Router()
|
|
|
|
super().__init__(request, client_address, server)
|
2019-07-21 17:40:28 +00:00
|
|
|
|
2019-09-22 18:51:33 +00:00
|
|
|
def log_message(self, format, *args):
|
2019-09-23 01:15:24 +00:00
|
|
|
logger.debug("%s - - [%s] %s", self.address_string(), self.log_date_time_string(), format % args)
|
2019-09-22 18:51:33 +00:00
|
|
|
|
2019-05-03 20:59:24 +00:00
|
|
|
def do_GET(self):
|
2020-06-10 18:09:40 +00:00
|
|
|
self.router.route(self, self.get_request("GET"))
|
2020-02-23 19:25:36 +00:00
|
|
|
|
|
|
|
def do_POST(self):
|
2020-06-10 18:09:40 +00:00
|
|
|
self.router.route(self, self.get_request("POST"))
|
|
|
|
|
2021-02-14 15:51:16 +00:00
|
|
|
def do_DELETE(self):
|
|
|
|
self.router.route(self, self.get_request("DELETE"))
|
|
|
|
|
2020-06-10 18:09:40 +00:00
|
|
|
def get_request(self, method):
|
|
|
|
url = urlparse(self.path)
|
|
|
|
return Request(url, method, self.headers)
|
2019-05-03 20:59:24 +00:00
|
|
|
|
2019-07-21 17:40:28 +00:00
|
|
|
|
2019-07-06 11:03:49 +00:00
|
|
|
class Request(object):
|
2020-06-10 18:09:40 +00:00
|
|
|
def __init__(self, url, method, headers):
|
2020-02-23 16:53:02 +00:00
|
|
|
self.path = url.path
|
|
|
|
self.query = parse_qs(url.query)
|
|
|
|
self.matches = None
|
2020-02-23 19:25:36 +00:00
|
|
|
self.method = method
|
2020-06-10 18:09:40 +00:00
|
|
|
self.headers = headers
|
|
|
|
self.cookies = SimpleCookie()
|
|
|
|
if "Cookie" in headers:
|
|
|
|
self.cookies.load(headers["Cookie"])
|
2020-02-23 16:53:02 +00:00
|
|
|
|
|
|
|
def setMatches(self, matches):
|
2019-07-06 11:03:49 +00:00
|
|
|
self.matches = matches
|
|
|
|
|
2019-07-21 17:40:28 +00:00
|
|
|
|
2020-02-23 16:53:02 +00:00
|
|
|
class Route(ABC):
|
2020-02-23 19:25:36 +00:00
|
|
|
def __init__(self, controller, method="GET", options=None):
|
2020-02-23 16:53:02 +00:00
|
|
|
self.controller = controller
|
2020-02-23 19:25:36 +00:00
|
|
|
self.controllerOptions = options if options is not None else {}
|
|
|
|
self.method = method
|
2020-02-23 16:53:02 +00:00
|
|
|
|
|
|
|
@abstractmethod
|
|
|
|
def matches(self, request):
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
class StaticRoute(Route):
|
2020-02-23 19:25:36 +00:00
|
|
|
def __init__(self, route, controller, method="GET", options=None):
|
2020-02-23 16:53:02 +00:00
|
|
|
self.route = route
|
2020-02-23 19:25:36 +00:00
|
|
|
super().__init__(controller, method, options)
|
2020-02-23 16:53:02 +00:00
|
|
|
|
|
|
|
def matches(self, request):
|
2020-02-23 19:25:36 +00:00
|
|
|
return request.path == self.route and self.method == request.method
|
2020-02-23 16:53:02 +00:00
|
|
|
|
|
|
|
|
|
|
|
class RegexRoute(Route):
|
2020-02-23 19:25:36 +00:00
|
|
|
def __init__(self, regex, controller, method="GET", options=None):
|
2020-02-23 16:53:02 +00:00
|
|
|
self.regex = re.compile(regex)
|
2020-02-23 19:25:36 +00:00
|
|
|
super().__init__(controller, method, options)
|
2020-02-23 16:53:02 +00:00
|
|
|
|
|
|
|
def matches(self, request):
|
|
|
|
matches = self.regex.match(request.path)
|
|
|
|
# this is probably not the cleanest way to do it...
|
|
|
|
request.setMatches(matches)
|
2020-02-23 19:25:36 +00:00
|
|
|
return matches is not None and self.method == request.method
|
2020-02-23 16:53:02 +00:00
|
|
|
|
|
|
|
|
2019-05-03 20:59:24 +00:00
|
|
|
class Router(object):
|
2020-02-23 16:53:02 +00:00
|
|
|
def __init__(self):
|
|
|
|
self.routes = [
|
|
|
|
StaticRoute("/", IndexController),
|
2020-06-01 14:03:22 +00:00
|
|
|
StaticRoute("/status.json", StatusController),
|
2020-02-23 16:53:02 +00:00
|
|
|
RegexRoute("/static/(.+)", OwrxAssetsController),
|
2020-05-02 11:35:42 +00:00
|
|
|
RegexRoute("/compiled/(.+)", CompiledAssetsController),
|
2020-02-23 16:53:02 +00:00
|
|
|
RegexRoute("/aprs-symbols/(.+)", AprsSymbolsController),
|
|
|
|
StaticRoute("/ws/", WebSocketController),
|
|
|
|
RegexRoute("(/favicon.ico)", OwrxAssetsController),
|
|
|
|
StaticRoute("/map", MapController),
|
|
|
|
StaticRoute("/features", FeatureController),
|
|
|
|
StaticRoute("/api/features", ApiController),
|
2021-02-01 17:43:14 +00:00
|
|
|
StaticRoute("/metrics", MetricsController, options={"action": "prometheusAction"}),
|
2021-02-01 17:26:26 +00:00
|
|
|
StaticRoute("/metrics.json", MetricsController),
|
2020-04-25 19:42:00 +00:00
|
|
|
StaticRoute("/settings", SettingsController),
|
2021-02-13 15:44:14 +00:00
|
|
|
StaticRoute("/settings/general", GeneralSettingsController),
|
2021-01-20 16:01:46 +00:00
|
|
|
StaticRoute(
|
2021-02-13 15:44:14 +00:00
|
|
|
"/settings/general", GeneralSettingsController, method="POST", options={"action": "processFormData"}
|
2021-01-20 16:01:46 +00:00
|
|
|
),
|
2021-02-13 15:44:14 +00:00
|
|
|
StaticRoute("/settings/sdr", SdrSettingsController),
|
2021-02-13 16:08:56 +00:00
|
|
|
StaticRoute("/settings/bookmarks", BookmarksController),
|
2021-02-14 15:21:09 +00:00
|
|
|
StaticRoute("/settings/bookmarks", BookmarksController, method="POST", options={"action": "new"}),
|
2021-02-13 23:41:03 +00:00
|
|
|
RegexRoute("/settings/bookmarks/(.+)", BookmarksController, method="POST", options={"action": "update"}),
|
2021-02-14 15:51:16 +00:00
|
|
|
RegexRoute("/settings/bookmarks/(.+)", BookmarksController, method="DELETE", options={"action": "delete"}),
|
2021-02-15 14:49:44 +00:00
|
|
|
StaticRoute("/settings/reporting", ReportingController),
|
|
|
|
StaticRoute(
|
|
|
|
"/settings/reporting", ReportingController, method="POST", options={"action": "processFormData"}
|
|
|
|
),
|
2021-02-15 14:56:17 +00:00
|
|
|
StaticRoute("/settings/backgrounddecoding", BackgroundDecodingController),
|
|
|
|
StaticRoute(
|
|
|
|
"/settings/backgrounddecoding",
|
|
|
|
BackgroundDecodingController,
|
|
|
|
method="POST",
|
|
|
|
options={"action": "processFormData"},
|
|
|
|
),
|
2021-02-15 15:06:14 +00:00
|
|
|
StaticRoute("/settings/decoding", DecodingSettingsController),
|
|
|
|
StaticRoute(
|
|
|
|
"/settings/decoding", DecodingSettingsController, method="POST", options={"action": "processFormData"}
|
|
|
|
),
|
2020-02-23 19:25:36 +00:00
|
|
|
StaticRoute("/login", SessionController, options={"action": "loginAction"}),
|
|
|
|
StaticRoute("/login", SessionController, method="POST", options={"action": "processLoginAction"}),
|
|
|
|
StaticRoute("/logout", SessionController, options={"action": "logoutAction"}),
|
2021-02-08 17:30:54 +00:00
|
|
|
StaticRoute("/pwchange", ProfileController),
|
|
|
|
StaticRoute("/pwchange", ProfileController, method="POST", options={"action": "processPwChange"}),
|
2021-02-08 22:29:24 +00:00
|
|
|
StaticRoute("/imageupload", ImageUploadController),
|
|
|
|
StaticRoute("/imageupload", ImageUploadController, method="POST", options={"action": "processImage"}),
|
2020-02-23 16:53:02 +00:00
|
|
|
]
|
|
|
|
|
|
|
|
def find_route(self, request):
|
|
|
|
for r in self.routes:
|
|
|
|
if r.matches(request):
|
|
|
|
return r
|
2019-07-21 17:40:28 +00:00
|
|
|
|
2020-06-10 18:09:40 +00:00
|
|
|
def route(self, handler, request):
|
2020-02-23 16:53:02 +00:00
|
|
|
route = self.find_route(request)
|
|
|
|
if route is not None:
|
|
|
|
controller = route.controller
|
2020-02-23 17:32:37 +00:00
|
|
|
controller(handler, request, route.controllerOptions).handle_request()
|
2019-05-03 20:59:24 +00:00
|
|
|
else:
|
|
|
|
handler.send_error(404, "Not Found", "The page you requested could not be found.")
|