Transparent redirect handler instead of returning HTTP 308 to clients

This commit is contained in:
Ian Renton
2026-08-12 18:49:06 +01:00
parent b9f2764085
commit c285b86131
9 changed files with 62 additions and 37 deletions
+47 -22
View File
@@ -1,29 +1,54 @@
import json
import tornado import tornado
from tornado.httpclient import AsyncHTTPClient
from core.utils import safe_json_dumps
class V1GoneHandler(tornado.web.RequestHandler):
"""Returns 410 Gone with a message for any endpoints in the old API that have breaking changes in the new one or
have been retired."""
def post(self):
self.set_status(410)
self.write(safe_json_dumps(
"This API endpoint has a breaking change or has been removed in the current version of the Spothole API. Please see /apidocs for details of the current API version and the endpoints available."))
self.set_header("Cache-Control", "no-store")
self.set_header("Content-Type", "application/json")
class V1RedirectHandler(tornado.web.RequestHandler): class V1RedirectHandler(tornado.web.RequestHandler):
"""Returns 308 Permanent Redirect from any path in the old API to the new one, where there were no breaking changes.""" """Transparently proxies requests from the old API to the new one,
returning whatever the v2 endpoint returns, for endpoints with no breaking changes."""
def get(self, path): SUPPORTED_METHODS = ("GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS")
new_url = "/api/v2/" + path
# Methods where an HTTP body isn't valid
_BODYLESS_METHODS = {"GET", "HEAD", "OPTIONS"}
async def _proxy(self, path):
new_url = f"{self.request.protocol}://{self.request.host}/api/v2/{path}"
if self.request.query: if self.request.query:
new_url += "?" + self.request.query new_url += "?" + self.request.query
self.set_status(308)
self.set_header("Location", new_url) client = AsyncHTTPClient()
try:
response = await client.fetch(
new_url,
method=self.request.method,
headers=self.request.headers,
body=None if self.request.method in self._BODYLESS_METHODS else (self.request.body or b""),
raise_error=False,
follow_redirects=False,
request_timeout=10.0,
)
except Exception as e:
raise tornado.web.HTTPError(502, reason=str(e))
self.set_status(response.code, response.reason)
for name, value in response.headers.get_all():
# Let Tornado recompute these for the outgoing response
if name.lower() not in ("content-length", "transfer-encoding", "connection"):
self.add_header(name, value)
if response.body:
self.write(response.body)
self.finish() self.finish()
async def get(self, path):
await self._proxy(path)
async def post(self, 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)
+1 -1
View File
@@ -76,7 +76,7 @@
</div> </div>
<script src="/static/js/add-spot.js?v=1786483250"></script> <script src="/static/js/add-spot.js?v=1786556946"></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>
+1 -1
View File
@@ -82,7 +82,7 @@
</div> </div>
<script src="/static/js/alerts.js?v=1786483250"></script> <script src="/static/js/alerts.js?v=1786556946"></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>
+2 -2
View File
@@ -79,8 +79,8 @@
</div> </div>
<script src="/static/js/spotsbandsandmap.js?v=1786483250"></script> <script src="/static/js/spotsbandsandmap.js?v=1786556946"></script>
<script src="/static/js/bands.js?v=1786483250"></script> <script src="/static/js/bands.js?v=1786556946"></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
View File
@@ -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=1786483250" type="text/css"> <link rel="stylesheet" href="/static/css/style.css?v=1786556946" 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">
@@ -10,10 +10,10 @@
<script src="/static/vendor/js/bootstrap-5.3.8.bundle.min.js"></script> <script src="/static/vendor/js/bootstrap-5.3.8.bundle.min.js"></script>
<script src="/static/vendor/js/tinycolor2-1.6.0.min.js"></script> <script src="/static/vendor/js/tinycolor2-1.6.0.min.js"></script>
<script src="/static/js/utils.js?v=1786483250"></script> <script src="/static/js/utils.js?v=1786556946"></script>
<script src="/static/js/ui-ham.js?v=1786483250"></script> <script src="/static/js/ui-ham.js?v=1786556946"></script>
<script src="/static/js/geo.js?v=1786483250"></script> <script src="/static/js/geo.js?v=1786556946"></script>
<script src="/static/js/common.js?v=1786483250"></script> <script src="/static/js/common.js?v=1786556946"></script>
{% end %} {% end %}
{% block body %} {% block body %}
<div class="container"> <div class="container">
+1 -1
View File
@@ -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=1786483250"></script> <script src="/static/js/conditions.js?v=1786556946"></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
View File
@@ -112,8 +112,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=1786483249"></script> <script src="/static/js/spotsbandsandmap.js?v=1786556946"></script>
<script src="/static/js/map.js?v=1786483249"></script> <script src="/static/js/map.js?v=1786556946"></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>
+2 -2
View File
@@ -118,8 +118,8 @@
</div> </div>
<script src="/static/js/spotsbandsandmap.js?v=1786483249"></script> <script src="/static/js/spotsbandsandmap.js?v=1786556946"></script>
<script src="/static/js/spots.js?v=1786483249"></script> <script src="/static/js/spots.js?v=1786556946"></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>
+1 -1
View File
@@ -81,7 +81,7 @@
</div> </div>
</div> </div>
<script src="/static/js/status.js?v=1786483250"></script> <script src="/static/js/status.js?v=1786556946"></script>
<script> <script>
$(document).ready(function () { $(document).ready(function () {
$("#nav-link-status").addClass("active"); $("#nav-link-status").addClass("active");