diff --git a/autopush/endpoint.py b/autopush/endpoint.py index 24b4870d..25d0ad60 100644 --- a/autopush/endpoint.py +++ b/autopush/endpoint.py @@ -445,10 +445,10 @@ def _uaid_lookup_results(self, result): try: self.router = self.ap_settings.routers[router_key] except KeyError: - log.msg("Client error", status_code=400, errno=108, + log.msg("Invalid router requested", status_code=400, errno=108, **self._client_info) return self._write_response(400, 108, - message="Invalid router type") + message="Invalid router") # Only simplepush uses version/data out of body/query, GCM/APNS will # use data out of the request body 'WebPush' style. @@ -598,9 +598,9 @@ def post(self, router_type="", router_token="", uaid="", chid=""): # normalize the path vars into parameters if router_type not in self.ap_settings.routers: - log.msg("Invalid parameters", **self._client_info) + log.msg("Invalid router requested", **self._client_info) return self._write_response( - 400, 108, message="Invalid arguments") + 400, 108, message="Invalid router") router = self.ap_settings.routers[router_type] valid, router_token = router.check_token(router_token) if not valid: @@ -651,9 +651,9 @@ def put(self, router_type="", router_token="", uaid="", chid=""): self.uaid = uaid router_data = params if router_type not in self.ap_settings.routers or not router_data: - log.msg("Invalid parameters", **self._client_info) + log.msg("Invalid router requested", **self._client_info) return self._write_response( - 400, 108, message="Invalid arguments") + 400, 108, message="Invalid router") router = self.ap_settings.routers[router_type] valid, router_token = router.check_token(router_token) if not valid: @@ -699,9 +699,9 @@ def delete(self, router_type="", router_token="", uaid="", chid=""): return self._write_unauthorized_response( message="Invalid Authentication") if router_type not in self.ap_settings.routers: - log.msg("Invalid parameters", **self._client_info) + log.msg("Invalid router requested", **self._client_info) return self._write_response( - 400, 108, message="Invalid arguments") + 400, 108, message="Invalid router") router = self.ap_settings.routers[router_type] valid, router_token = router.check_token(router_token) if not valid: diff --git a/autopush/router/gcm.py b/autopush/router/gcm.py index c3872ffc..78bbe4ce 100644 --- a/autopush/router/gcm.py +++ b/autopush/router/gcm.py @@ -13,14 +13,13 @@ class GCMRouter(object): """GCM Router Implementation""" gcm = None - ttl = 60 dryRun = 0 collapseKey = "simplepush" def __init__(self, ap_settings, router_conf): """Create a new GCM router and connect to GCM""" self.config = router_conf - self.ttl = router_conf.get("ttl", 60) + self.min_ttl = router_conf.get("ttl", 60) self.dryRun = router_conf.get("dryrun", False) self.collapseKey = router_conf.get("collapseKey", "simplepush") self.senderIDs = router_conf.get("senderIDs") @@ -100,10 +99,11 @@ def _route(self, notification, router_data): # registration_ids are the GCM instance tokens (specified during # registration. + router_ttl = notification.ttl or 0 payload = gcmclient.JSONMessage( registration_ids=[router_data.get("token")], collapse_key=self.collapseKey, - time_to_live=self.ttl, + time_to_live=max(self.min_ttl, router_ttl), dry_run=self.dryRun or ("dryrun" in router_data), data=data, ) diff --git a/autopush/tests/test_router.py b/autopush/tests/test_router.py index f9b74a46..014dedfd 100644 --- a/autopush/tests/test_router.py +++ b/autopush/tests/test_router.py @@ -165,6 +165,7 @@ def setUp(self, fgcm): ) self.gcm_config = {'s3_bucket': 'None', 'max_data': 32, + 'ttl': 60, 'senderid_list': {'test123': {"auth": "12345678abcdefg"}}} self.gcm = fgcm @@ -242,6 +243,30 @@ def check_results(result): d.addCallback(check_results) return d + def test_ttl_none(self): + self.router.gcm = self.gcm + self.notif = Notification(version=10, + data="\xab\xad\x1d\xea", + channel_id=dummy_chid, + headers=self.headers, + ttl=None) + d = self.router.route_notification(self.notif, self.router_data) + + def check_results(result): + ok_(isinstance(result, RouterResponse)) + assert(self.router.gcm.send.called) + # Make sure the data was encoded as base64 + data = self.router.gcm.send.call_args[0][0].data + options = self.router.gcm.send.call_args[0][0].options + eq_(data['body'], 'q60d6g==') + eq_(data['enc'], 'test') + eq_(data['enckey'], 'test') + eq_(data['con'], 'aesgcm') + # use the defined min TTL + eq_(options['time_to_live'], 60) + d.addCallback(check_results) + return d + def test_long_data(self): self.router.gcm = self.gcm badNotif = Notification( diff --git a/configs/autopush_endpoint.ini b/configs/autopush_endpoint.ini index 8f867e13..fbfd65ee 100644 --- a/configs/autopush_endpoint.ini +++ b/configs/autopush_endpoint.ini @@ -25,6 +25,10 @@ port = 8082 ; GCM requires a API Auth key. It is STRONGLY recommended you use one specific to this app. #gcm_apikey = +; Minimum GCM Time To Live value. Set this in case of excessive loss of +; TTL 0 messages across the GCM bridge +#gcm_ttl = 0 + ; AuthKey are the keys to use for Bearer Auth tokens. It uses the same ; autokey generator as the crypto_key argument, and sorted [newest, oldest] #auth_key = [HJVPy4ZwF4Yz_JdvXTL8hRcwIhv742vC60Tg5Ycrvw8=]