Skip to content

Commit 3aadc60

Browse files
committed
feat: Allow empty payloads
closes #40
1 parent c80a56c commit 3aadc60

File tree

5 files changed

+59
-27
lines changed

5 files changed

+59
-27
lines changed

circle.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# circle ci file
2+
machine:
3+
post:
4+
- pyenv global 2.7.13 3.5
5+
6+
dependencies:
7+
pre:
8+
- pip install -r test-requirements.txt
9+
10+
test:
11+
override:
12+
- nosetests -v pywebpush

pywebpush/__init__.py

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ def encode(self, data):
152152
'body': encrypted,
153153
})
154154

155-
def send(self, data, headers=None, ttl=0, gcm_key=None, reg_id=None):
155+
def send(self, data=None, headers=None, ttl=0, gcm_key=None, reg_id=None):
156156
"""Encode and send the data to the Push Service.
157157
158158
:param data: A serialized block of data (see encode() ).
@@ -169,22 +169,25 @@ def send(self, data, headers=None, ttl=0, gcm_key=None, reg_id=None):
169169
# Encode the data.
170170
if headers is None:
171171
headers = dict()
172-
encoded = self.encode(data)
173-
# Append the p256dh to the end of any existing crypto-key
172+
encoded = {}
174173
headers = CaseInsensitiveDict(headers)
175-
crypto_key = headers.get("crypto-key", "")
176-
if crypto_key:
177-
# due to some confusion by a push service provider, we should
178-
# use ';' instead of ',' to append the headers.
179-
# see https://github.com/webpush-wg/webpush-encryption/issues/6
180-
crypto_key += ';'
181-
crypto_key += "keyid=p256dh;dh=" + encoded["crypto_key"].decode('utf8')
182-
headers.update({
183-
'crypto-key': crypto_key,
184-
'content-encoding': 'aesgcm',
185-
'encryption': "keyid=p256dh;salt=" +
186-
encoded['salt'].decode('utf8'),
187-
})
174+
if data:
175+
encoded = self.encode(data)
176+
# Append the p256dh to the end of any existing crypto-key
177+
crypto_key = headers.get("crypto-key", "")
178+
if crypto_key:
179+
# due to some confusion by a push service provider, we should
180+
# use ';' instead of ',' to append the headers.
181+
# see https://github.com/webpush-wg/webpush-encryption/issues/6
182+
crypto_key += ';'
183+
crypto_key += (
184+
"keyid=p256dh;dh=" + encoded["crypto_key"].decode('utf8'))
185+
headers.update({
186+
'crypto-key': crypto_key,
187+
'content-encoding': 'aesgcm',
188+
'encryption': "keyid=p256dh;salt=" +
189+
encoded['salt'].decode('utf8'),
190+
})
188191
gcm_endpoint = 'https://android.googleapis.com/gcm/send'
189192
if self.subscription_info['endpoint'].startswith(gcm_endpoint):
190193
if not gcm_key:
@@ -194,13 +197,14 @@ def send(self, data, headers=None, ttl=0, gcm_key=None, reg_id=None):
194197
if not reg_id:
195198
reg_id = self.subscription_info['endpoint'].rsplit('/', 1)[-1]
196199
reg_ids.append(reg_id)
197-
data = dict()
198-
data['registration_ids'] = reg_ids
199-
data['raw_data'] = base64.b64encode(
200-
encoded.get('body')).decode('utf8')
201-
data['time_to_live'] = int(
200+
gcm_data = dict()
201+
gcm_data['registration_ids'] = reg_ids
202+
if data:
203+
gcm_data['raw_data'] = base64.b64encode(
204+
encoded.get('body')).decode('utf8')
205+
gcm_data['time_to_live'] = int(
202206
headers['ttl'] if 'ttl' in headers else ttl)
203-
encoded_data = json.dumps(data)
207+
encoded_data = json.dumps(gcm_data)
204208
headers.update({
205209
'Authorization': 'key='+gcm_key,
206210
'Content-Type': 'application/json',

pywebpush/tests/test_webpush.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
import os
44
import unittest
55

6-
import http_ece
76
from mock import patch
87
from nose.tools import eq_, ok_
8+
import http_ece
99
import pyelliptic
1010

1111
from pywebpush import WebPusher, WebPushException, CaseInsensitiveDict
@@ -83,11 +83,11 @@ def test_encode(self):
8383
push._repad(subscription_info['keys']['auth']))
8484

8585
decoded = http_ece.decrypt(
86-
buffer=encoded['body'],
86+
encoded['body'],
8787
salt=raw_salt,
8888
dh=raw_dh,
8989
keyid=keyid,
90-
authSecret=raw_auth
90+
authSecret=raw_auth,
9191
)
9292

9393
eq_(decoded.decode('utf8'), data)
@@ -109,6 +109,22 @@ def test_send(self, mock_post):
109109
ok_('pre-existing' in ckey)
110110
eq_(pheaders.get('content-encoding'), 'aesgcm')
111111

112+
@patch("requests.post")
113+
def test_send_empty(self, mock_post):
114+
recv_key = pyelliptic.ECC(curve="prime256v1")
115+
subscription_info = self._gen_subscription_info(recv_key)
116+
headers = {"Crypto-Key": "pre-existing",
117+
"Authentication": "bearer vapid"}
118+
data = None
119+
WebPusher(subscription_info).send(data, headers)
120+
eq_(subscription_info.get('endpoint'), mock_post.call_args[0][0])
121+
pheaders = mock_post.call_args[1].get('headers')
122+
eq_(pheaders.get('ttl'), '0')
123+
ok_('encryption' not in pheaders)
124+
eq_(pheaders.get('AUTHENTICATION'), headers.get('Authentication'))
125+
ckey = pheaders.get('crypto-key')
126+
ok_('pre-existing' in ckey)
127+
112128
@patch("requests.post")
113129
def test_send_no_headers(self, mock_post):
114130
recv_key = pyelliptic.ECC(curve="prime256v1")

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
http-ece==0.5.0
1+
http-ece==0.7.0
22
python-jose>1.2.0
33
requests>2.11.0
44
flake8

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
from setuptools import find_packages, setup
55

6-
__version__ = "0.6.2"
6+
__version__ = "0.6.3"
77

88

99
def read_from(file):

0 commit comments

Comments
 (0)