2018-10-14 14:42:28 +00:00
|
|
|
"""Simple endpoint that redirects to the embedded fully qualified URL.
|
|
|
|
|
2019-01-04 15:17:45 +00:00
|
|
|
May also instead fetch and convert to AS2, depending on conneg.
|
|
|
|
|
2018-10-14 14:42:28 +00:00
|
|
|
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
|
|
|
|
"""
|
2019-04-16 15:02:19 +00:00
|
|
|
import datetime
|
2019-01-04 15:17:45 +00:00
|
|
|
import json
|
2019-04-16 15:02:19 +00:00
|
|
|
import logging
|
2018-10-14 14:42:28 +00:00
|
|
|
|
2019-01-04 15:17:45 +00:00
|
|
|
from granary import as2, microformats2
|
|
|
|
import mf2py
|
|
|
|
import mf2util
|
2019-04-16 15:02:19 +00:00
|
|
|
from oauth_dropins.webutil.handlers import memcache_response
|
2018-10-14 14:42:28 +00:00
|
|
|
import webapp2
|
|
|
|
|
|
|
|
import appengine_config
|
|
|
|
import common
|
|
|
|
|
2019-04-16 15:02:19 +00:00
|
|
|
CACHE_TIME = datetime.timedelta(seconds=15)
|
|
|
|
|
2018-10-14 14:42:28 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
"""
|
|
|
|
|
2019-04-16 15:02:19 +00:00
|
|
|
@memcache_response(CACHE_TIME)
|
2018-10-14 14:42:28 +00:00
|
|
|
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)
|
2019-01-04 15:17:45 +00:00
|
|
|
|
|
|
|
# poor man's conneg, only handle single Accept values, not multiple with
|
|
|
|
# priorities.
|
|
|
|
if self.request.headers.get('Accept') in (common.CONTENT_TYPE_AS2,
|
|
|
|
common.CONTENT_TYPE_AS2_LD):
|
|
|
|
return self.convert_to_as2(to)
|
|
|
|
|
|
|
|
# redirect
|
2018-10-14 14:42:28 +00:00
|
|
|
logging.info('redirecting to %s', to)
|
|
|
|
self.redirect(to)
|
|
|
|
|
2019-01-04 15:17:45 +00:00
|
|
|
def convert_to_as2(self, url):
|
|
|
|
"""Fetch a URL as HTML, convert it to AS2, and return it.
|
|
|
|
|
|
|
|
Currently mainly for Pixelfed.
|
|
|
|
https://github.com/snarfed/bridgy-fed/issues/39
|
|
|
|
"""
|
|
|
|
resp = common.requests_get(url)
|
|
|
|
mf2 = mf2py.parse(resp.text, url=resp.url, img_with_alt=True)
|
|
|
|
entry = mf2util.find_first_entry(mf2, ['h-entry'])
|
|
|
|
logging.info('Parsed mf2 for %s: %s', resp.url, json.dumps(entry, indent=2))
|
|
|
|
|
|
|
|
obj = common.postprocess_as2(as2.from_as1(microformats2.json_to_object(entry)))
|
|
|
|
logging.info('Returning: %s', json.dumps(obj, indent=2))
|
|
|
|
|
|
|
|
self.response.headers.update({
|
|
|
|
'Content-Type': common.CONTENT_TYPE_AS2,
|
|
|
|
'Access-Control-Allow-Origin': '*',
|
|
|
|
})
|
|
|
|
self.response.write(json.dumps(obj, indent=2))
|
|
|
|
|
2018-10-14 14:42:28 +00:00
|
|
|
|
|
|
|
app = webapp2.WSGIApplication([
|
|
|
|
(r'/r/.+', RedirectHandler),
|
|
|
|
], debug=appengine_config.DEBUG)
|