don't store a Response for OStatus/Salmon unless we actually attempt delivery

pull/79/head
Ryan Barrett 2021-07-20 15:55:16 -07:00
rodzic 2e3360a54b
commit b23705e97e
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 6BE31FDF4776E9D4
2 zmienionych plików z 23 dodań i 20 usunięć

Wyświetl plik

@ -285,6 +285,7 @@ class WebmentionTest(testutil.TestCase):
mock_get.side_effect = ValueError('foo bar')
got = client.post('/webmention', data={'source': 'bad'})
self.assertEqual(400, got.status_code)
self.assertEqual(0, Response.query().count())
def test_no_source_entry(self, mock_get, mock_post):
mock_get.return_value = requests_response("""
@ -299,6 +300,7 @@ class WebmentionTest(testutil.TestCase):
'target': 'https://fed.brid.gy/',
})
self.assertEqual(400, got.status_code)
self.assertEqual(0, Response.query().count())
mock_get.assert_has_calls((self.req('http://a/post'),))
@ -315,6 +317,7 @@ class WebmentionTest(testutil.TestCase):
'target': 'https://fed.brid.gy/',
})
self.assertEqual(200, got.status_code)
self.assertEqual(0, Response.query().count())
mock_get.assert_has_calls((self.req('http://a/post'),))
@ -326,6 +329,7 @@ class WebmentionTest(testutil.TestCase):
got = client.post('/webmention', data={'source': 'http://a/post'})
self.assertEqual(400, got.status_code)
self.assertEqual(0, Response.query().count())
def test_source_fetch_fails(self, mock_get, mock_post):
mock_get.side_effect = (
@ -343,6 +347,7 @@ class WebmentionTest(testutil.TestCase):
)
got = client.post('/webmention', data={'source': 'http://a/post'})
self.assertEqual(502, got.status_code)
self.assertEqual(0, Response.query().count())
def test_no_backlink(self, mock_get, mock_post):
mock_get.return_value = requests_response(
@ -354,6 +359,7 @@ class WebmentionTest(testutil.TestCase):
'target': 'https://fed.brid.gy/',
})
self.assertEqual(400, got.status_code)
self.assertEqual(0, Response.query().count())
mock_get.assert_has_calls((self.req('http://a/post'),))
@ -851,8 +857,7 @@ class WebmentionTest(testutil.TestCase):
self.assertEqual(400, got.status_code)
self.assertIn('Target post http://orig/url has no Atom link',
got.get_data(as_text=True))
self.assertIsNone(Response.get_by_id('http://a/reply http://orig/post'))
self.assertEqual(0, Response.query().count())
def test_salmon_relative_atom_href(self, mock_get, mock_post):
orig_relative = requests_response("""\

Wyświetl plik

@ -115,7 +115,7 @@ class Webmention(View):
# Pass the AP response status code and body through as our response
if last_success:
return last_success.text, last_success.status_code
return last_success.text or 'Sent!', last_success.status_code
elif isinstance(error, (requests.HTTPError, exc.HTTPBadGateway)):
return str(error), error.status_code
else:
@ -228,35 +228,34 @@ class Webmention(View):
logging.warning("No targets or followers. Ignoring.")
return
resp = Response.get_or_create(
source=self.source_url, target=target, direction='out',
source_mf2=json_dumps(self.source_mf2))
resp.protocol = 'ostatus'
status = None
try:
ret = self._try_salmon(resp)
resp.status = 'complete'
ret = self._try_salmon(target)
if isinstance(ret, str):
status = 'complete'
return ret
except:
resp.status = 'error'
status = 'error'
raise
finally:
resp.put()
if status:
Response(source=self.source_url, target=target, status=status,
direction='out', protocol = 'ostatus',
source_mf2=json_dumps(self.source_mf2)).put()
def _try_salmon(self, resp):
def _try_salmon(self, target):
"""
Args:
resp: Response
target: string
"""
# fetch target HTML page, extract Atom rel-alternate link
target = resp.target()
if not self.target_resp:
self.target_resp = common.requests_get(target)
parsed = util.parse_html(self.target_resp)
atom_url = parsed.find('link', rel='alternate', type=common.CONTENT_TYPE_ATOM)
if not atom_url or not atom_url.get('href'):
return error(f'Target post {resp.target()} has no Atom link')
return error(f'Target post {target} has no Atom link')
# fetch Atom target post, extract and inject id into source object
base_url = ''
@ -265,7 +264,7 @@ class Webmention(View):
base_url = base['href']
atom_link = parsed.find('link', rel='alternate', type=common.CONTENT_TYPE_ATOM)
atom_url = urllib.parse.urljoin(
resp.target(), urllib.parse.urljoin(base_url, atom_link['href']))
target, urllib.parse.urljoin(base_url, atom_link['href']))
feed = common.requests_get(atom_url).text
parsed = feedparser.parse(feed)
@ -297,7 +296,7 @@ class Webmention(View):
if not endpoint:
# try webfinger
parsed = urllib.parse.urlparse(resp.target())
parsed = urllib.parse.urlparse(target)
# TODO: test missing email
author = entry.get('author_detail', {})
email = author.get('email') or '@'.join(
@ -316,7 +315,6 @@ class Webmention(View):
logging.info(f'Discovered Salmon endpoint {endpoint}')
# construct reply Atom object
self.source_url = resp.source()
activity = self.source_obj
if self.source_obj.get('verb') not in source.VERBS_WITH_OBJECT:
activity = {'object': self.source_obj}
@ -335,7 +333,7 @@ class Webmention(View):
endpoint, data=common.XML_UTF8 + magic_envelope,
headers={'Content-Type': common.CONTENT_TYPE_MAGIC_ENVELOPE})
return ''
return 'Sent!'
app.add_url_rule('/webmention', view_func=Webmention.as_view('webmention'),