kopia lustrzana https://github.com/snarfed/bridgy-fed
Flask port: error handling bug fixes, other misc tweaks
rodzic
5913a9ea6a
commit
cf12817212
|
@ -12,9 +12,7 @@ from granary import as2, microformats2
|
|||
import mf2util
|
||||
from oauth_dropins.webutil import util
|
||||
from oauth_dropins.webutil.flask_util import error
|
||||
from oauth_dropins.webutil.handlers import cache_response
|
||||
from oauth_dropins.webutil.util import json_dumps, json_loads
|
||||
import webapp2
|
||||
|
||||
from app import app, cache
|
||||
import common
|
||||
|
|
3
app.py
3
app.py
|
@ -7,7 +7,6 @@ from oauth_dropins.webutil import (
|
|||
appengine_info,
|
||||
appengine_config,
|
||||
flask_util,
|
||||
handlers,
|
||||
util,
|
||||
)
|
||||
|
||||
|
@ -29,7 +28,7 @@ app.register_error_handler(Exception, flask_util.handle_exception)
|
|||
# don't redirect API requests with blank path elements
|
||||
app.url_map.redirect_defaults = True
|
||||
|
||||
app.wsgi_app = handlers.ndb_context_middleware(
|
||||
app.wsgi_app = flask_util.ndb_context_middleware(
|
||||
app.wsgi_app, client=appengine_config.ndb_client)
|
||||
|
||||
cache = Cache(app)
|
||||
|
|
13
common.py
13
common.py
|
@ -10,8 +10,9 @@ import urllib.parse
|
|||
from flask import request
|
||||
from granary import as2
|
||||
from oauth_dropins.webutil import util, webmention
|
||||
from oauth_dropins.webutil.flask_util import error
|
||||
import requests
|
||||
from webob import exc
|
||||
from werkzeug.exceptions import BadGateway
|
||||
|
||||
from models import Response
|
||||
|
||||
|
@ -108,15 +109,15 @@ def get_as2(url):
|
|||
:class:`requests.Response`
|
||||
|
||||
Raises:
|
||||
:class:`requests.HTTPError`, :class:`webob.exc.HTTPException`
|
||||
:class:`requests.HTTPError`, :class:`werkzeug.exceptions.HTTPException`
|
||||
|
||||
If we raise webob HTTPException, it will have an additional response
|
||||
attribute with the last requests.Response we received.
|
||||
If we raise a werkzeug HTTPException, it will have an additional
|
||||
response attribute with the last requests.Response we received.
|
||||
"""
|
||||
def _error(resp):
|
||||
msg = "Couldn't fetch %s as ActivityStreams 2" % url
|
||||
logging.warning(msg)
|
||||
err = exc.HTTPBadGateway(msg)
|
||||
err = BadGateway(msg)
|
||||
err.response = resp
|
||||
raise err
|
||||
|
||||
|
@ -155,7 +156,7 @@ def send_webmentions(activity_wrapped, proxy=None, **response_props):
|
|||
|
||||
verb = activity.get('verb')
|
||||
if verb and verb not in SUPPORTED_VERBS:
|
||||
error('%s activities are not supported yet.' % verb)
|
||||
error(f'{verb} activities are not supported yet.')
|
||||
|
||||
# extract source and targets
|
||||
source = activity.get('url') or activity.get('id')
|
||||
|
|
|
@ -7,7 +7,7 @@ from unittest import mock
|
|||
from oauth_dropins.webutil import util
|
||||
from oauth_dropins.webutil.testutil import requests_response
|
||||
import requests
|
||||
from webob import exc
|
||||
from werkzeug.exceptions import BadGateway
|
||||
|
||||
from app import app
|
||||
import common
|
||||
|
@ -50,17 +50,17 @@ class CommonTest(testutil.TestCase):
|
|||
|
||||
@mock.patch('requests.get', return_value=HTML)
|
||||
def test_get_as2_only_html(self, mock_get):
|
||||
with self.assertRaises(exc.HTTPBadGateway):
|
||||
with self.assertRaises(BadGateway):
|
||||
resp = common.get_as2('http://orig')
|
||||
|
||||
@mock.patch('requests.get', return_value=NOT_ACCEPTABLE)
|
||||
def test_get_as2_not_acceptable(self, mock_get):
|
||||
with self.assertRaises(exc.HTTPBadGateway):
|
||||
with self.assertRaises(BadGateway):
|
||||
resp = common.get_as2('http://orig')
|
||||
|
||||
@mock.patch('requests.get', side_effect=requests.exceptions.SSLError)
|
||||
def test_get_ssl_error(self, mock_get):
|
||||
with self.assertRaises(exc.HTTPBadGateway):
|
||||
with self.assertRaises(BadGateway):
|
||||
resp = common.get_as2('http://orig')
|
||||
|
||||
def test_redirect_wrap_empty(self):
|
||||
|
|
|
@ -340,10 +340,14 @@ class WebmentionTest(testutil.TestCase):
|
|||
got = client.post('/webmention', data={'source': 'http://a/post'})
|
||||
self.assertEqual(502, got.status_code)
|
||||
|
||||
def test_source_fetch_has_no_content_type(self, mock_get, mock_post):
|
||||
def test_target_fetch_has_no_content_type(self, mock_get, mock_post):
|
||||
html = self.reply_html.replace(
|
||||
'</body>',
|
||||
"<link href='http://as2' rel='alternate' type='application/activity+json'></body")
|
||||
mock_get.side_effect = (
|
||||
requests_response(self.reply_html),
|
||||
requests_response(self.reply_html, content_type='None')
|
||||
# http://not/fediverse
|
||||
requests_response(self.reply_html, content_type='None'),
|
||||
)
|
||||
got = client.post('/webmention', data={'source': 'http://a/post'})
|
||||
self.assertEqual(502, got.status_code)
|
||||
|
@ -709,7 +713,7 @@ class WebmentionTest(testutil.TestCase):
|
|||
})
|
||||
body = got.get_data(as_text=True)
|
||||
self.assertEqual(502, got.status_code, body)
|
||||
self.assertEqual(
|
||||
self.assertIn(
|
||||
'405 Client Error: None for url: https://foo.com/inbox ; abc xyz',
|
||||
body)
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@ from unittest.mock import ANY, call
|
|||
from oauth_dropins.webutil import testutil, util
|
||||
from oauth_dropins.webutil.appengine_config import ndb_client
|
||||
import requests
|
||||
import webapp2
|
||||
|
||||
import common
|
||||
|
||||
|
@ -23,10 +22,6 @@ class TestCase(unittest.TestCase, testutil.Asserts):
|
|||
self.ndb_context = ndb_client.context()
|
||||
self.ndb_context.__enter__()
|
||||
|
||||
self.request = webapp2.Request.blank('/')
|
||||
self.response = webapp2.Response()
|
||||
# self.handler = common.Handler(self.request, self.response)
|
||||
|
||||
def tearDown(self):
|
||||
self.ndb_context.__exit__(None, None, None)
|
||||
super().tearDown()
|
||||
|
|
|
@ -11,10 +11,9 @@ import urllib.parse
|
|||
from flask import render_template, request
|
||||
from granary.microformats2 import get_text
|
||||
import mf2util
|
||||
from oauth_dropins.webutil import flask_util, handlers, util
|
||||
from oauth_dropins.webutil import flask_util, util
|
||||
from oauth_dropins.webutil.flask_util import error
|
||||
from oauth_dropins.webutil.util import json_dumps
|
||||
import webapp2
|
||||
|
||||
from app import app, cache
|
||||
import common
|
||||
|
|
|
@ -20,8 +20,7 @@ from oauth_dropins.webutil import flask_util, util
|
|||
from oauth_dropins.webutil.flask_util import error
|
||||
from oauth_dropins.webutil.util import json_dumps, json_loads
|
||||
import requests
|
||||
import webapp2
|
||||
from webob import exc
|
||||
from werkzeug.exceptions import BadGateway
|
||||
|
||||
import activitypub
|
||||
from app import app
|
||||
|
@ -116,7 +115,9 @@ class Webmention(View):
|
|||
# Pass the AP response status code and body through as our response
|
||||
if last_success:
|
||||
return last_success.text or 'Sent!', last_success.status_code
|
||||
elif isinstance(error, (requests.HTTPError, exc.HTTPBadGateway)):
|
||||
elif isinstance(error, BadGateway):
|
||||
raise error
|
||||
elif isinstance(error, requests.HTTPError):
|
||||
return str(error), error.status_code
|
||||
else:
|
||||
return str(error)
|
||||
|
@ -164,7 +165,7 @@ class Webmention(View):
|
|||
# fetch target page as AS2 object
|
||||
try:
|
||||
self.target_resp = common.get_as2(target)
|
||||
except (requests.HTTPError, exc.HTTPBadGateway) as e:
|
||||
except (requests.HTTPError, BadGateway) as e:
|
||||
self.target_resp = getattr(e, 'response', None)
|
||||
if self.target_resp and self.target_resp.status_code // 100 == 2:
|
||||
content_type = common.content_type(self.target_resp) or ''
|
||||
|
|
Ładowanie…
Reference in New Issue