55import datetime
66import hmac
77import hashlib
8- from six .moves .urllib .parse import quote
8+ from six .moves .urllib .parse import urlencode
99
1010
1111class SignerV4 (object ):
@@ -41,9 +41,8 @@ def sign(path, method, headers, body, query, ak, sk, region, service):
4141
4242 signed_headers_string = ';' .join (sorted (signed_headers .keys ()))
4343
44- canonical_request = '\n ' .join (
45- [method , path , SignerV4 .norm_query (query ), signed_str ,
46- signed_headers_string , body_hash ])
44+ # The sorted() method sorts tuples by default, using the first item in each tuple.
45+ canonical_request = '\n ' .join ([method , path , urlencode (sorted (query )), signed_str , signed_headers_string , body_hash ])
4746 credential_scope = '/' .join ([format_date [:8 ], region , service , 'request' ])
4847 signing_str = '\n ' .join (['HMAC-SHA256' , format_date , credential_scope ,
4948 hashlib .sha256 (canonical_request .encode ('utf-8' )).hexdigest ()])
@@ -67,19 +66,3 @@ def get_signing_secret_key_v4(sk, date, region, service):
6766 @staticmethod
6867 def hmac_sha256 (key , msg ):
6968 return hmac .new (key , msg .encode ('utf-8' ), hashlib .sha256 ).digest ()
70-
71- @staticmethod
72- def norm_query (params ):
73- query = ''
74- for key in sorted (params .keys ()):
75- if type (params [key ]) == list :
76- for k in params [key ]:
77- query = query + quote (key , safe = '-_.~' ) + '=' + quote (k , safe = '-_.~' ) + '&'
78- elif type (params [key ]) in [int , float , bool ]:
79- # The argument to urllib.parse.quote must be a string
80- ele = str (params [key ])
81- query = query + quote (key , safe = '-_.~' ) + '=' + quote (ele , safe = '-_.~' ) + '&'
82- else :
83- query = query + quote (key , safe = '-_.~' ) + '=' + quote (params [key ], safe = '-_.~' ) + '&'
84- query = query [:- 1 ]
85- return query .replace ('+' , '%20' )
0 commit comments