diff --git a/app.yaml b/app.yaml index b6ec854..ff877db 100644 --- a/app.yaml +++ b/app.yaml @@ -67,6 +67,10 @@ handlers: script: logs.app secure: always +- url: /r/.+ + script: redirect.app + secure: always + - url: /wm/.+ script: add_webmention.app secure: always diff --git a/redirect.py b/redirect.py new file mode 100644 index 0000000..6895cc2 --- /dev/null +++ b/redirect.py @@ -0,0 +1,34 @@ +"""Simple endpoint that redirects to the embedded fully qualified URL. + +Used to wrap ActivityPub ids with the fed.brid.gy domain so that Mastodon +accepts them. Background: + +https://github.com/snarfed/bridgy-fed/issues/16#issuecomment-424799599 +https://github.com/tootsuite/mastodon/pull/6219#issuecomment-429142747 +""" +import logging + +import webapp2 + +import appengine_config +import common + + +class RedirectHandler(webapp2.RequestHandler): + """301 redirects to the embedded fully qualified URL. + + e.g. redirects /r/https://foo.com/bar?baz to https://foo.com/bar?baz + """ + + def get(self): + assert self.request.path_qs.startswith('/r/') + to = self.request.path_qs[3:] + if not to.startswith('http://') and not to.startswith('https://'): + common.error(self, 'Expected fully qualified URL; got %s' % to) + logging.info('redirecting to %s', to) + self.redirect(to) + + +app = webapp2.WSGIApplication([ + (r'/r/.+', RedirectHandler), +], debug=appengine_config.DEBUG) diff --git a/tests/test_redirect.py b/tests/test_redirect.py new file mode 100644 index 0000000..41e236d --- /dev/null +++ b/tests/test_redirect.py @@ -0,0 +1,20 @@ +"""Unit tests for redirect.py. +""" +from redirect import app +import testutil + + +class ActivityPubTest(testutil.TestCase): + + def test_redirect(self): + got = app.get_response('/r/https://foo.com/bar?baz=baj&biff') + self.assertEqual(302, got.status_int) + self.assertEqual('https://foo.com/bar?baz=baj&biff', got.headers['Location']) + + def test_redirect_scheme_missing(self): + got = app.get_response('/r/asdf.com') + self.assertEqual(400, got.status_int) + + def test_redirect_url_missing(self): + got = app.get_response('/r/') + self.assertEqual(404, got.status_int)