@@ -14,6 +14,33 @@ class WebPushException(Exception):
1414 pass
1515
1616
17+ class CaseInsensitiveDict (dict ):
18+ """A dictionary that has case-insensitive keys"""
19+
20+ def __init__ (self , data = {}, ** kwargs ):
21+ for key in data :
22+ dict .__setitem__ (self , key .lower (), data [key ])
23+ self .update (kwargs )
24+
25+ def __contains__ (self , key ):
26+ return dict .__contains__ (self , key .lower ())
27+
28+ def __setitem__ (self , key , value ):
29+ dict .__setitem__ (self , key .lower (), value )
30+
31+ def __getitem__ (self , key ):
32+ return dict .__getitem__ (self , key .lower ())
33+
34+ def __delitem__ (self , key ):
35+ dict .__delitem__ (self , key .lower ())
36+
37+ def get (self , key , default = None ):
38+ try :
39+ return self .__getitem__ (key )
40+ except KeyError :
41+ return default
42+
43+
1744class WebPusher :
1845 """WebPusher encrypts a data block using HTTP Encrypted Content Encoding
1946 for WebPush.
@@ -68,11 +95,13 @@ def __init__(self, subscription_info):
6895 for k in ['p256dh' , 'auth' ]:
6996 if keys .get (k ) is None :
7097 raise WebPushException ("Missing keys value: %s" , k )
71- receiver_raw = base64 .urlsafe_b64decode (self ._repad (keys ['p256dh' ]))
98+ receiver_raw = base64 .urlsafe_b64decode (
99+ self ._repad (keys ['p256dh' ].encode ('utf8' )))
72100 if len (receiver_raw ) != 65 and receiver_raw [0 ] != "\x04 " :
73101 raise WebPushException ("Invalid p256dh key specified" )
74102 self .receiver_key = receiver_raw
75- self .auth_key = base64 .urlsafe_b64decode (self ._repad (keys ['auth' ]))
103+ self .auth_key = base64 .urlsafe_b64decode (
104+ self ._repad (keys ['auth' ].encode ('utf8' )))
76105
77106 def _repad (self , str ):
78107 """Add base64 padding to the end of a string, if required"""
@@ -96,7 +125,7 @@ def encode(self, data):
96125 server_key_id = base64 .urlsafe_b64encode (server_key .get_pubkey ()[1 :])
97126
98127 # http_ece requires that these both be set BEFORE encrypt or
99- # decrypt is called.
128+ # decrypt is called if you specify the key as "dh" .
100129 http_ece .keys [server_key_id ] = server_key
101130 http_ece .labels [server_key_id ] = "P-256"
102131
@@ -107,12 +136,12 @@ def encode(self, data):
107136 dh = self .receiver_key ,
108137 authSecret = self .auth_key )
109138
110- return {
139+ return CaseInsensitiveDict ( {
111140 'crypto_key' : base64 .urlsafe_b64encode (
112141 server_key .get_pubkey ()).strip ('=' ),
113142 'salt' : base64 .urlsafe_b64encode (salt ).strip ("=" ),
114143 'body' : encrypted ,
115- }
144+ })
116145
117146 def send (self , data , headers = {}, ttl = 0 ):
118147 """Encode and send the data to the Push Service.
@@ -127,6 +156,7 @@ def send(self, data, headers={}, ttl=0):
127156 # Encode the data.
128157 encoded = self .encode (data )
129158 # Append the p256dh to the end of any existing crypto-key
159+ headers = CaseInsensitiveDict (headers )
130160 crypto_key = headers .get ("crypto-key" , "" )
131161 if crypto_key :
132162 crypto_key += ','
0 commit comments