AP users: ignore webmention sending failures

since webmention support is optional for web users: https://fed.brid.gy/docs#error-handling

for #512
pull/530/head
Ryan Barrett 2023-06-04 15:11:52 -07:00
rodzic 1366842bba
commit 71dadc2ba5
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 6BE31FDF4776E9D4
4 zmienionych plików z 61 dodań i 5 usunięć

Wyświetl plik

@ -277,7 +277,7 @@ class Protocol:
follower_obj.status = 'active'
follower_obj.put()
# send AP Accept
# send Accept
followee_actor_url = g.user.ap_actor()
accept = {
'@context': 'https://www.w3.org/ns/activitystreams',

Wyświetl plik

@ -768,6 +768,31 @@ class ActivityPubTest(TestCase):
labels=['notification', 'activity'],
object_ids=[FOLLOW['object']])
def test_inbox_follow_accept_webmention_fails(self, mock_head, mock_get, mock_post):
mock_post.side_effect = [
requests_response(), # AP Accept
requests.ConnectionError(), # webmention
]
self._test_inbox_follow_accept(FOLLOW_WRAPPED, ACCEPT,
mock_head, mock_get, mock_post)
follow = {
**FOLLOW_WITH_ACTOR,
'url': 'https://mas.to/users/swentel#followed-https://user.com/',
}
self.assert_object('https://mas.to/6d1a',
domains=['user.com'],
source_protocol='activitypub',
status='complete',
as2=follow,
delivered=[],
type='follow',
labels=['notification', 'activity'],
object_ids=[FOLLOW['object']])
follower = Follower.query().get()
self.assertEqual(follow, follower.last_follow)
def _test_inbox_follow_accept(self, follow_as2, accept_as2,
mock_head, mock_get, mock_post):
mock_head.return_value = requests_response(url='https://user.com/')
@ -776,7 +801,8 @@ class ActivityPubTest(TestCase):
self.as2_resp(ACTOR),
WEBMENTION_DISCOVERY,
]
mock_post.return_value = requests_response()
if not mock_post.return_value and not mock_post.side_effect:
mock_post.return_value = requests_response()
got = self.post('/user.com/inbox', json=follow_as2)
self.assertEqual(200, got.status_code)

Wyświetl plik

@ -14,6 +14,7 @@ from oauth_dropins.webutil.appengine_info import APP_ID
from oauth_dropins.webutil.testutil import requests_response
from oauth_dropins.webutil.util import json_dumps, json_loads
import requests
from requests import HTTPError
from werkzeug.exceptions import BadGateway, BadRequest
# import first so that Fake is defined before URL routes are registered
@ -1699,6 +1700,26 @@ class WebProtocolTest(testutil.TestCase):
self.assert_req(mock_get, 'https://user.com/post')
mock_post.assert_not_called()
def test_send_errors(self, mock_get, mock_post):
for err in [
requests.HTTPError(response=util.Struct(status_code='429', text='')),
requests.ConnectionError(),
]:
mock_get.return_value = WEBMENTION_REL_LINK
mock_post.side_effect = err
obj = Object(id='http://mas.to/like#ok', as2=test_activitypub.LIKE,
source_protocol='ui')
self.assertFalse(Web.send(obj, 'https://user.com/post'))
self.assert_req(mock_get, 'https://user.com/post')
args, kwargs = mock_post.call_args
self.assertEqual(('https://user.com/webmention',), args)
self.assertEqual({
'source': 'http://localhost/convert/ui/web/http:/mas.to/like^^ok',
'target': 'https://user.com/post',
}, kwargs['data'])
def test_serve(self, _, __):
obj = Object(id='http://orig', mf2=ACTOR_MF2)
html, headers = Web.serve(obj)

15
web.py
Wyświetl plik

@ -155,14 +155,23 @@ class Web(User, Protocol):
"""Sends a webmention to a given target URL.
See :meth:`Protocol.send` for details.
*Does not* propagate HTTP errors, DNS or connection failures, or other
exceptions, since webmention support is optional for web recipients.
https://fed.brid.gy/docs#error-handling
"""
source_url = obj.proxy_url()
logger.info(f'Sending webmention from {source_url} to {url}')
endpoint = common.webmention_discover(url).endpoint
if endpoint:
webmention.send(endpoint, source_url, url)
return True
try:
if endpoint:
webmention.send(endpoint, source_url, url)
return True
except RequestException as e:
# log exception, then ignore it
util.interpret_http_exception(e)
return False
@classmethod
def fetch(cls, obj, gateway=False, check_backlink=None):