1111logger = logging .getLogger (__name__ )
1212
1313
14+ def filter_headers (data ):
15+ """只设置host content-type 还有x开头的头部.
16+
17+ :param data(dict): 所有的头部信息.
18+ :return(dict): 计算进签名的头部.
19+ """
20+ headers = {}
21+ for i in data .keys ():
22+ if i == 'Content-Type' or i == 'Host' or i [0 ] == 'x' or i [0 ] == 'X' :
23+ headers [i ] = data [i ]
24+ return headers
25+
26+
27+ def to_string (data ):
28+ """转换unicode为string.
29+
30+ :param data(unicode|string): 待转换的unicode|string.
31+ :return(string): 转换后的string.
32+ """
33+ if isinstance (data , unicode ):
34+ return data .encode ('utf8' )
35+ return data
36+
37+
1438class CosS3Auth (AuthBase ):
1539
16- def __init__ (self , access_id , secret_key , expire = 10000 ):
17- self ._access_id = access_id
18- self ._secret_key = secret_key
40+ def __init__ (self , secret_id , secret_key , key = '' , params = {} , expire = 10000 ):
41+ self ._secret_id = to_string ( secret_id )
42+ self ._secret_key = to_string ( secret_key )
1943 self ._expire = expire
44+ self ._params = params
45+ if key :
46+ if key [0 ] == '/' :
47+ self ._path = key
48+ else :
49+ self ._path = '/' + key
50+ else :
51+ self ._path = '/'
2052
2153 def __call__ (self , r ):
22- method = r .method .lower ()
23- uri = urllib .unquote (r .url )
24- uri = uri .split ('?' )[0 ]
25- http_header = r .headers
26- r .headers = {}
27- rt = urlparse (uri )
28- logger .debug ("url parse: " + str (rt ))
29- if rt .query != "" and ("&" in rt .query or '=' in rt .query ):
30- uri_params = dict (map (lambda s : s .lower ().split ('=' ), rt .query .split ('&' )))
31- elif rt .query != "" :
32- uri_params = {rt .query : "" }
33- else :
34- uri_params = {}
35- headers = dict ([(k .lower (), quote (v ).lower ()) for k , v in r .headers .items ()])
54+ path = self ._path
55+ uri_params = self ._params
56+ headers = filter_headers (r .headers )
57+ # reserved keywords in headers urlencode are -_.~, notice that / should be encoded and space should not be encoded to plus sign(+)
58+ headers = dict ([(k .lower (), quote (v , '-_.~' )) for k , v in headers .items ()]) # headers中的key转换为小写,value进行encode
3659 format_str = "{method}\n {host}\n {params}\n {headers}\n " .format (
37- method = method .lower (),
38- host = rt . path ,
39- params = urllib .urlencode (uri_params ),
60+ method = r . method .lower (),
61+ host = path ,
62+ params = urllib .urlencode (sorted ( uri_params . items ()) ),
4063 headers = '&' .join (map (lambda (x , y ): "%s=%s" % (x , y ), sorted (headers .items ())))
4164 )
4265 logger .debug ("format str: " + format_str )
4366
4467 start_sign_time = int (time .time ())
45- sign_time = "{bg_time};{ed_time}" .format (bg_time = start_sign_time - 60 , ed_time = start_sign_time + self ._expire )
68+ sign_time = "{bg_time};{ed_time}" .format (bg_time = start_sign_time - 60 , ed_time = start_sign_time + self ._expire )
4669 sha1 = hashlib .sha1 ()
4770 sha1 .update (format_str )
4871
@@ -54,18 +77,16 @@ def __call__(self, r):
5477 logger .debug ('sign: ' + str (sign ))
5578 sign_tpl = "q-sign-algorithm=sha1&q-ak={ak}&q-sign-time={sign_time}&q-key-time={key_time}&q-header-list={headers}&q-url-param-list={params}&q-signature={sign}"
5679
57- http_header ['Authorization' ] = sign_tpl .format (
58- ak = self ._access_id ,
80+ r . headers ['Authorization' ] = sign_tpl .format (
81+ ak = self ._secret_id ,
5982 sign_time = sign_time ,
6083 key_time = sign_time ,
6184 params = ';' .join (sorted (map (lambda k : k .lower (), uri_params .keys ()))),
6285 headers = ';' .join (sorted (headers .keys ())),
6386 sign = sign
6487 )
65- r .headers = http_header
6688 logger .debug ("sign_key" + str (sign_key ))
6789 logger .debug (r .headers ['Authorization' ])
68-
6990 logger .debug ("request headers: " + str (r .headers ))
7091 return r
7192
0 commit comments