mirror of
https://git.ianrenton.com/ian/spothole.git
synced 2026-09-20 22:37:44 +00:00
Re-add translation of QRZ/HamQTH query params to header params, since it turns out someone was using that
This commit is contained in:
@@ -3,27 +3,39 @@ from tornado.httpclient import AsyncHTTPClient
|
|||||||
from tornado.httputil import HTTPHeaders
|
from tornado.httputil import HTTPHeaders
|
||||||
|
|
||||||
|
|
||||||
|
_LEGACY_PARAM_TO_HEADER_MAP = {
|
||||||
|
"qrz_username": "X-QRZ-Username",
|
||||||
|
"qrz_password": "X-QRZ-Password",
|
||||||
|
"qrz_session_key": "X-QRZ-Session-Key",
|
||||||
|
"hamqth_username": "X-HamQTH-Username",
|
||||||
|
"hamqth_password": "X-HamQTH-Password",
|
||||||
|
"hamqth_session_id": "X-HamQTH-Session-ID",
|
||||||
|
}
|
||||||
|
|
||||||
class V1RedirectHandler(tornado.web.RequestHandler):
|
class V1RedirectHandler(tornado.web.RequestHandler):
|
||||||
"""Transparently proxies requests from the old API to the new one,
|
"""Transparently proxies requests from the old API to the new one,
|
||||||
returning whatever the v2 endpoint returns, for endpoints with no breaking changes."""
|
returning whatever the v2 endpoint returns, for endpoints with no breaking changes."""
|
||||||
|
|
||||||
SUPPORTED_METHODS = ("GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS")
|
|
||||||
|
|
||||||
# Methods where an HTTP body isn't valid
|
|
||||||
_BODYLESS_METHODS = {"GET", "HEAD", "OPTIONS"}
|
|
||||||
|
|
||||||
async def _proxy(self, path):
|
async def _proxy(self, path):
|
||||||
new_url = f"{self.request.protocol}://{self.request.host}/api/v2/{path}"
|
new_url = f"{self.request.protocol}://{self.request.host}/api/v2/{path}"
|
||||||
if self.request.query:
|
if self.request.query:
|
||||||
new_url += f"?{self.request.query}"
|
new_url += f"?{self.request.query}"
|
||||||
|
|
||||||
|
# Copy the incoming headers so we can add translated legacy credentials without changing the original
|
||||||
|
# request.
|
||||||
|
headers = HTTPHeaders(self.request.headers)
|
||||||
|
for param, header in _LEGACY_PARAM_TO_HEADER_MAP.items():
|
||||||
|
value = self.get_query_argument(param, default=None)
|
||||||
|
if value:
|
||||||
|
headers[header] = value
|
||||||
|
|
||||||
client = AsyncHTTPClient()
|
client = AsyncHTTPClient()
|
||||||
try:
|
try:
|
||||||
response = await client.fetch(
|
response = await client.fetch(
|
||||||
new_url,
|
new_url,
|
||||||
method=self.request.method,
|
method=self.request.method,
|
||||||
headers=self.request.headers,
|
headers=self.request.headers,
|
||||||
body=None if self.request.method in self._BODYLESS_METHODS else (self.request.body or b""),
|
body=None if self.request.method == "GET" else (self.request.body or b""),
|
||||||
raise_error=False,
|
raise_error=False,
|
||||||
follow_redirects=False,
|
follow_redirects=False,
|
||||||
request_timeout=10.0,
|
request_timeout=10.0,
|
||||||
@@ -49,12 +61,3 @@ class V1RedirectHandler(tornado.web.RequestHandler):
|
|||||||
|
|
||||||
async def post(self, path):
|
async def post(self, path):
|
||||||
await self._proxy(path)
|
await self._proxy(path)
|
||||||
|
|
||||||
async def put(self, path):
|
|
||||||
await self._proxy(path)
|
|
||||||
|
|
||||||
async def delete(self, path):
|
|
||||||
await self._proxy(path)
|
|
||||||
|
|
||||||
async def patch(self, path):
|
|
||||||
await self._proxy(path)
|
|
||||||
|
|||||||
@@ -3,11 +3,33 @@ import re
|
|||||||
from server.handlers.api.spots import APISpotsHandler, APISpotsStreamHandler
|
from server.handlers.api.spots import APISpotsHandler, APISpotsStreamHandler
|
||||||
|
|
||||||
_GRID_SOURCE_RE = re.compile(r'"dx_location_source":\s*"GRID"')
|
_GRID_SOURCE_RE = re.compile(r'"dx_location_source":\s*"GRID"')
|
||||||
|
_LEGACY_PARAM_TO_HEADER_MAP = {
|
||||||
|
"qrz_username": "X-QRZ-Username",
|
||||||
|
"qrz_password": "X-QRZ-Password",
|
||||||
|
"qrz_session_key": "X-QRZ-Session-Key",
|
||||||
|
"hamqth_username": "X-HamQTH-Username",
|
||||||
|
"hamqth_password": "X-HamQTH-Password",
|
||||||
|
"hamqth_session_id": "X-HamQTH-Session-ID",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _handle_legacy_params(handler):
|
||||||
|
"""Copy v1 query-string QRZ/HamQTH credentials into the v2 headers, so the v2 handler can see them"""
|
||||||
|
|
||||||
|
for param, header in _LEGACY_PARAM_TO_HEADER_MAP.items():
|
||||||
|
if header in handler.request.headers:
|
||||||
|
continue
|
||||||
|
value = handler.get_query_argument(param, default=None)
|
||||||
|
if value:
|
||||||
|
handler.request.headers[header] = value
|
||||||
|
|
||||||
class V1APISpotsHandler(APISpotsHandler):
|
class V1APISpotsHandler(APISpotsHandler):
|
||||||
"""API request handler for /api/v1/spots (GET). Included in early Spothole v2 for backwards compatibility."""
|
"""API request handler for /api/v1/spots (GET). Included in early Spothole v2 for backwards compatibility."""
|
||||||
|
|
||||||
|
def prepare(self):
|
||||||
|
_handle_legacy_params(self)
|
||||||
|
super().prepare()
|
||||||
|
|
||||||
def write(self, chunk):
|
def write(self, chunk):
|
||||||
if isinstance(chunk, str):
|
if isinstance(chunk, str):
|
||||||
chunk = _GRID_SOURCE_RE.sub('"dx_location_source": "SPOT"', chunk)
|
chunk = _GRID_SOURCE_RE.sub('"dx_location_source": "SPOT"', chunk)
|
||||||
@@ -17,6 +39,10 @@ class V1APISpotsHandler(APISpotsHandler):
|
|||||||
class V1APISpotsStreamHandler(APISpotsStreamHandler):
|
class V1APISpotsStreamHandler(APISpotsStreamHandler):
|
||||||
"""API request handler for /api/v1/spots/stream (SSE). Included in early Spothole v2 for backwards compatibility."""
|
"""API request handler for /api/v1/spots/stream (SSE). Included in early Spothole v2 for backwards compatibility."""
|
||||||
|
|
||||||
|
def prepare(self):
|
||||||
|
_handle_legacy_params(self)
|
||||||
|
super().prepare()
|
||||||
|
|
||||||
def write_message(self, *args, **kwargs):
|
def write_message(self, *args, **kwargs):
|
||||||
args = list(args)
|
args = list(args)
|
||||||
for i, a in enumerate(args):
|
for i, a in enumerate(args):
|
||||||
|
|||||||
@@ -76,7 +76,7 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="/static/js/add-spot.js?v=1786885905"></script>
|
<script src="/static/js/add-spot.js?v=1786890185"></script>
|
||||||
<script>$(document).ready(function () {
|
<script>$(document).ready(function () {
|
||||||
$("#nav-link-add-spot").addClass("active");
|
$("#nav-link-add-spot").addClass("active");
|
||||||
}); <!-- highlight active page in nav --></script>
|
}); <!-- highlight active page in nav --></script>
|
||||||
|
|||||||
@@ -84,7 +84,7 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="/static/js/alerts.js?v=1786885905"></script>
|
<script src="/static/js/alerts.js?v=1786890185"></script>
|
||||||
<script>$(document).ready(function () {
|
<script>$(document).ready(function () {
|
||||||
$("#nav-link-alerts").addClass("active");
|
$("#nav-link-alerts").addClass("active");
|
||||||
}); <!-- highlight active page in nav --></script>
|
}); <!-- highlight active page in nav --></script>
|
||||||
|
|||||||
@@ -76,8 +76,8 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="/static/js/spotsbandsandmap.js?v=1786885905"></script>
|
<script src="/static/js/spotsbandsandmap.js?v=1786890185"></script>
|
||||||
<script src="/static/js/bands.js?v=1786885905"></script>
|
<script src="/static/js/bands.js?v=1786890185"></script>
|
||||||
<script>$(document).ready(function () {
|
<script>$(document).ready(function () {
|
||||||
$("#nav-link-bands").addClass("active");
|
$("#nav-link-bands").addClass("active");
|
||||||
}); <!-- highlight active page in nav --></script>
|
}); <!-- highlight active page in nav --></script>
|
||||||
|
|||||||
+5
-5
@@ -1,6 +1,6 @@
|
|||||||
{% extends "skeleton.html" %}
|
{% extends "skeleton.html" %}
|
||||||
{% block head_extra %}
|
{% block head_extra %}
|
||||||
<link rel="stylesheet" href="/static/css/style.css?v=1786885905" type="text/css">
|
<link rel="stylesheet" href="/static/css/style.css?v=1786890185" type="text/css">
|
||||||
<link href="/static/vendor/css/bootstrap-5.3.8.min.css" rel="stylesheet">
|
<link href="/static/vendor/css/bootstrap-5.3.8.min.css" rel="stylesheet">
|
||||||
<link href="/static/vendor/css/fontawesome-6.7.2.min.css" rel="stylesheet">
|
<link href="/static/vendor/css/fontawesome-6.7.2.min.css" rel="stylesheet">
|
||||||
<link href="/static/vendor/css/solid-6.7.2.min.css" rel="stylesheet">
|
<link href="/static/vendor/css/solid-6.7.2.min.css" rel="stylesheet">
|
||||||
@@ -15,10 +15,10 @@
|
|||||||
window.fetchEventSource = fetchEventSource;
|
window.fetchEventSource = fetchEventSource;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script src="/static/js/utils.js?v=1786885905"></script>
|
<script src="/static/js/utils.js?v=1786890185"></script>
|
||||||
<script src="/static/js/ui-ham.js?v=1786885905"></script>
|
<script src="/static/js/ui-ham.js?v=1786890185"></script>
|
||||||
<script src="/static/js/geo.js?v=1786885905"></script>
|
<script src="/static/js/geo.js?v=1786890185"></script>
|
||||||
<script src="/static/js/common.js?v=1786885905"></script>
|
<script src="/static/js/common.js?v=1786890185"></script>
|
||||||
{% end %}
|
{% end %}
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
|||||||
@@ -284,7 +284,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="/static/vendor/js/chart-4.4.9.umd.min.js"></script>
|
<script src="/static/vendor/js/chart-4.4.9.umd.min.js"></script>
|
||||||
<script src="/static/js/conditions.js?v=1786885905"></script>
|
<script src="/static/js/conditions.js?v=1786890185"></script>
|
||||||
<script>$(document).ready(function () {
|
<script>$(document).ready(function () {
|
||||||
$("#nav-link-conditions").addClass("active");
|
$("#nav-link-conditions").addClass("active");
|
||||||
}); <!-- highlight active page in nav --></script>
|
}); <!-- highlight active page in nav --></script>
|
||||||
|
|||||||
+2
-2
@@ -109,8 +109,8 @@
|
|||||||
<script src="/static/vendor/js/leaflet-cqzones.js"></script>
|
<script src="/static/vendor/js/leaflet-cqzones.js"></script>
|
||||||
<script src="/static/vendor/js/leaflet-workedallbritainireland.js" type="module"></script>
|
<script src="/static/vendor/js/leaflet-workedallbritainireland.js" type="module"></script>
|
||||||
|
|
||||||
<script src="/static/js/spotsbandsandmap.js?v=1786885905"></script>
|
<script src="/static/js/spotsbandsandmap.js?v=1786890185"></script>
|
||||||
<script src="/static/js/map.js?v=1786885905"></script>
|
<script src="/static/js/map.js?v=1786890185"></script>
|
||||||
<script>$(document).ready(function () {
|
<script>$(document).ready(function () {
|
||||||
$("#nav-link-map").addClass("active");
|
$("#nav-link-map").addClass("active");
|
||||||
}); <!-- highlight active page in nav --></script>
|
}); <!-- highlight active page in nav --></script>
|
||||||
|
|||||||
@@ -113,8 +113,8 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="/static/js/spotsbandsandmap.js?v=1786885905"></script>
|
<script src="/static/js/spotsbandsandmap.js?v=1786890185"></script>
|
||||||
<script src="/static/js/spots.js?v=1786885905"></script>
|
<script src="/static/js/spots.js?v=1786890185"></script>
|
||||||
<script>$(document).ready(function () {
|
<script>$(document).ready(function () {
|
||||||
$("#nav-link-spots").addClass("active");
|
$("#nav-link-spots").addClass("active");
|
||||||
}); <!-- highlight active page in nav --></script>
|
}); <!-- highlight active page in nav --></script>
|
||||||
|
|||||||
@@ -86,7 +86,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="/static/js/status.js?v=1786885905"></script>
|
<script src="/static/js/status.js?v=1786890185"></script>
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
$("#nav-link-status").addClass("active");
|
$("#nav-link-status").addClass("active");
|
||||||
|
|||||||
Reference in New Issue
Block a user