From 23180c7db00bf39f96cf867ac1ac44c3a946bfc7 Mon Sep 17 00:00:00 2001 From: Ryan Barrett Date: Tue, 15 Aug 2017 07:42:29 -0700 Subject: [PATCH] add /wm/... URL proxy that injects our webmention endpoint --- add_webmention.py | 41 +++++++++++++++++++++++++++++++++++++ app.yaml | 13 +++++++----- test/test_add_webmention.py | 32 +++++++++++++++++++++++++++++ webmention.py | 1 + 4 files changed, 82 insertions(+), 5 deletions(-) create mode 100644 add_webmention.py create mode 100644 test/test_add_webmention.py diff --git a/add_webmention.py b/add_webmention.py new file mode 100644 index 0000000..552e5c4 --- /dev/null +++ b/add_webmention.py @@ -0,0 +1,41 @@ +"""HTTP proxy that injects our webmention endpoint. +""" +import logging + +import appengine_config + +import requests +import webapp2 + +import common + +LINK_HEADER = '<%s/webmention>; rel="webmention"' + + +class AddWebmentionHandler(webapp2.RequestHandler): + """Proxies HTTP requests and adds Link header to our webmention endpoint.""" + + def get(self, url): + if not url.startswith('http://') and not url.startswith('https://'): + self.abort(400, 'URL must start with http:// or https://') + + try: + resp = common.requests_get(url) + except requests.exceptions.Timeout as e: + logging.info('Returning 504 due to', exc_info=True) + self.abort(504, unicode(e)) + except requests.exceptions.RequestException as e: + logging.info('Returning 502 due to', exc_info=True) + self.abort(502, unicode(e)) + + self.response.status_int = resp.status_code + self.response.write(resp.content) + + self.response.headers.clear() + self.response.headers.update(resp.headers) + self.response.headers.add('Link', LINK_HEADER % self.request.host_url) + + +app = webapp2.WSGIApplication([ + ('/wm/(.+)', AddWebmentionHandler), +], debug=appengine_config.DEBUG) diff --git a/app.yaml b/app.yaml index 906b55c..d3ec14d 100644 --- a/app.yaml +++ b/app.yaml @@ -35,14 +35,17 @@ handlers: upload: static/index.html # dynamic -- url: /[^/]+/?(inbox)? - script: activitypub.app - # TODO - # secure: always +- url: /wm/.+ + script: add_webmention.app + secure: always - url: /webmention script: webmention.app - # secure: always + secure: always + +- url: /[^/]+/?(inbox)? + script: activitypub.app + secure: always skip_files: - ^(.*/)?.*\.py[co] diff --git a/test/test_add_webmention.py b/test/test_add_webmention.py new file mode 100644 index 0000000..3c342be --- /dev/null +++ b/test/test_add_webmention.py @@ -0,0 +1,32 @@ +# coding=utf-8 +"""Unit tests for add_webmention.py. +""" +import unittest + +import mock +import requests + +from add_webmention import app + + +@mock.patch('requests.get') +class AddWebmentionTest(unittest.TestCase): + + def setUp(self): + self.resp = requests.Response() + self.resp._content = 'asdf ☕ qwert' + self.resp.headers = { + 'Link': 'first', + 'Foo': 'bar', + } + + def test_get(self, mock_get): + self.resp.status_code = 202 + mock_get.return_value = self.resp + + got = app.get_response('/wm/http://url') + self.assertEqual(202, got.status_int) + self.assertEqual(self.resp._content, got.body) + self.assertEqual(['bar'], got.headers.getall('Foo')) + self.assertEqual(['first', '; rel="webmention"'], + got.headers.getall('Link')) diff --git a/webmention.py b/webmention.py index 6a7021f..8e67fa9 100644 --- a/webmention.py +++ b/webmention.py @@ -10,6 +10,7 @@ from granary import microformats2 import mf2py import mf2util from oauth_dropins.webutil import util +import requests import webapp2 import activitypub