better response codes and log information for failed push requests

This commit is contained in:
Kyle Mahan 2016-03-18 16:33:20 +00:00
parent 0c88cbf7c1
commit 860756a0f2
2 changed files with 27 additions and 20 deletions

View file

@ -31,13 +31,14 @@ def notify(feed_id):
if not feed: if not feed:
current_app.logger.warn( current_app.logger.warn(
'could not find feed corresponding to %d', feed_id) 'could not find feed corresponding to %d', feed_id)
abort(404) return make_response('no feed with id %d' % feed_id, 400)
if topic != feed.push_topic: if topic != feed.push_topic:
current_app.logger.warn( current_app.logger.warn(
'feed topic (%s) does not match subscription request (%s)', 'feed topic (%s) does not match subscription request (%s)',
feed.push_topic, topic) feed.push_topic, topic)
abort(404) return make_response(
'topic %s does not match subscription request %s' % (feed.push_topic, topic), 400)
current_app.logger.debug( current_app.logger.debug(
'PuSH verify subscribe for feed=%r, topic=%s', feed, topic) 'PuSH verify subscribe for feed=%r, topic=%s', feed, topic)
@ -48,18 +49,28 @@ def notify(feed_id):
db.session.commit() db.session.commit()
return challenge return challenge
elif mode == 'unsubscribe' and (not feed or topic != feed.push_topic): elif mode == 'unsubscribe':
current_app.logger.debug( if not feed or topic != feed.push_topic:
'PuSH verify unsubscribe for feed=%r, topic=%s', feed, topic) current_app.logger.debug(
return challenge 'PuSH verify unsubscribe for feed=%r, topic=%s', feed, topic)
current_app.logger.debug('PuSH cannot verify %s for feed=%r, topic=%s', return challenge
mode, feed, topic) else:
abort(404) current_app.logger.debug(
'PuSH denying unsubscribe for feed=%r, topic=%s', feed, topic)
return make_response('unsubscribe denied', 400)
elif mode:
current_app.logger.debug('PuSH request with unknown mode %s', mode)
return make_response('unrecognized hub.mode=%s' % mode, 400)
else:
current_app.logger.debug('PuSH request with no mode')
return make_response('missing requred parameter hub.mode', 400)
if not feed: if not feed:
current_app.logger.warn( current_app.logger.warn(
'could not find feed corresponding to %d', feed_id) 'could not find feed corresponding to %d', feed_id)
abort(404) return make_response('no feed with id %d' % feed_id, 400)
# could it be? an actual push notification!? # could it be? an actual push notification!?
current_app.logger.debug( current_app.logger.debug(
@ -83,7 +94,7 @@ def notify(feed_id):
content = request.data.decode('utf-8') content = request.data.decode('utf-8')
tasks.q_high.enqueue(tasks.update_feed, feed.id, tasks.q_high.enqueue(tasks.update_feed, feed.id,
content=content, content_type=content_type, content=content, content_type=content_type,
is_polling=False) is_polling=False)
feed.last_pinged = datetime.datetime.utcnow() feed.last_pinged = datetime.datetime.utcnow()
db.session.commit() db.session.commit()

View file

@ -1,5 +1,5 @@
from contextlib import contextmanager from contextlib import contextmanager
from flask import current_app from flask import current_app, url_for
from redis import StrictRedis from redis import StrictRedis
from woodwind import util from woodwind import util
from woodwind.extensions import db from woodwind.extensions import db
@ -231,21 +231,17 @@ def update_feed(feed_id, content=None,
def check_push_subscription(feed, response): def check_push_subscription(feed, response):
def build_callback_url():
return '{}://{}/_notify/{}'.format(
getattr(current_app.config, 'PREFERRED_URL_SCHEME', 'http'),
current_app.config['SERVER_NAME'],
feed.id)
def send_request(mode, hub, topic): def send_request(mode, hub, topic):
hub = urllib.parse.urljoin(feed.feed, hub) hub = urllib.parse.urljoin(feed.feed, hub)
topic = urllib.parse.urljoin(feed.feed, topic) topic = urllib.parse.urljoin(feed.feed, topic)
callback = url_for('push.notify', feed_id=feed.id, _external=True)
current_app.logger.debug( current_app.logger.debug(
'sending %s request for hub=%r, topic=%r', mode, hub, topic) 'sending %s request for hub=%r, topic=%r, callback=%r',
mode, hub, topic, callback)
r = requests.post(hub, data={ r = requests.post(hub, data={
'hub.mode': mode, 'hub.mode': mode,
'hub.topic': topic, 'hub.topic': topic,
'hub.callback': build_callback_url(), 'hub.callback': callback,
'hub.secret': feed.get_or_create_push_secret(), 'hub.secret': feed.get_or_create_push_secret(),
'hub.verify': 'sync', # backcompat with 0.3 'hub.verify': 'sync', # backcompat with 0.3
}) })