1- # -*- coding: utf-8 -*-
2- import hmac
3- import time
4- import urllib
5- import hashlib
6- import logging
7- import requests
8- from urllib import quote
9- from urlparse import urlparse
10- from requests .auth import AuthBase
11- logger = logging .getLogger (__name__ )
12-
13-
14- class CosS3Auth (AuthBase ):
15-
16- def __init__ (self , access_id , secret_key , expire = 10000 ):
17- self ._access_id = access_id
18- self ._secret_key = secret_key
19- self ._expire = expire
20-
21- def __call__ (self , r ):
22- method = r .method .lower ()
23- uri = urllib .unquote (r .url )
24- uri = uri .split ('?' )[0 ]
25- rt = urlparse (uri )
26- logger .debug ("url parse: " + str (rt ))
27- if rt .query != "" and ("&" in rt .query or '=' in rt .query ):
28- uri_params = dict (map (lambda s : s .lower ().split ('=' ), rt .query .split ('&' )))
29- elif rt .query != "" :
30- uri_params = {rt .query : "" }
31- else :
32- uri_params = {}
33- r .headers = {}
34- r .headers ['Host' ] = rt .netloc
35- headers = dict ([(k .lower (), quote (v ).lower ()) for k , v in r .headers .items ()])
36- 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 ),
40- headers = '&' .join (map (lambda (x , y ): "%s=%s" % (x , y ), sorted (headers .items ())))
41- )
42- logger .debug ("format str: " + format_str )
43-
44- 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 )
46- sha1 = hashlib .sha1 ()
47- sha1 .update (format_str )
48-
49- str_to_sign = "sha1\n {time}\n {sha1}\n " .format (time = sign_time , sha1 = sha1 .hexdigest ())
50- logger .debug ('str_to_sign: ' + str (str_to_sign ))
51- sign_key = hmac .new (self ._secret_key , sign_time , hashlib .sha1 ).hexdigest ()
52- sign = hmac .new (sign_key , str_to_sign , hashlib .sha1 ).hexdigest ()
53- logger .debug ('sign_key: ' + str (sign_key ))
54- logger .debug ('sign: ' + str (sign ))
55- 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}"
56-
57- r .headers ['Authorization' ] = sign_tpl .format (
58- ak = self ._access_id ,
59- sign_time = sign_time ,
60- key_time = sign_time ,
61- params = ';' .join (sorted (map (lambda k : k .lower (), uri_params .keys ()))),
62- headers = ';' .join (sorted (headers .keys ())),
63- sign = sign
64- )
65- logger .debug ("sign_key" + str (sign_key ))
66- logger .debug (r .headers ['Authorization' ])
67-
68- logger .debug ("request headers: " + str (r .headers ))
69- return r
70-
71-
72- if __name__ == "__main__" :
73- url = 'http://lewzylu01-1252448703.cn-south.myqcloud.com/a.txt'
1+ # -*- coding: utf-8 -*-
2+ import hmac
3+ import time
4+ import urllib
5+ import hashlib
6+ import logging
7+ import requests
8+ from urllib import quote
9+ from urlparse import urlparse
10+ from requests .auth import AuthBase
11+ logger = logging .getLogger (__name__ )
12+
13+ #fix a bug which can't send header
14+ class CosS3Auth (AuthBase ):
15+
16+ def __init__ (self , access_id , secret_key , expire = 10000 ):
17+ self ._access_id = access_id
18+ self ._secret_key = secret_key
19+ self ._expire = expire
20+
21+ 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 ()])
36+ 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 ),
40+ headers = '&' .join (map (lambda (x , y ): "%s=%s" % (x , y ), sorted (headers .items ())))
41+ )
42+ logger .debug ("format str: " + format_str )
43+
44+ 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 )
46+ sha1 = hashlib .sha1 ()
47+ sha1 .update (format_str )
48+
49+ str_to_sign = "sha1\n {time}\n {sha1}\n " .format (time = sign_time , sha1 = sha1 .hexdigest ())
50+ logger .debug ('str_to_sign: ' + str (str_to_sign ))
51+ sign_key = hmac .new (self ._secret_key , sign_time , hashlib .sha1 ).hexdigest ()
52+ sign = hmac .new (sign_key , str_to_sign , hashlib .sha1 ).hexdigest ()
53+ logger .debug ('sign_key: ' + str (sign_key ))
54+ logger .debug ('sign: ' + str (sign ))
55+ 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}"
56+
57+ http_header ['Authorization' ] = sign_tpl .format (
58+ ak = self ._access_id ,
59+ sign_time = sign_time ,
60+ key_time = sign_time ,
61+ params = ';' .join (sorted (map (lambda k : k .lower (), uri_params .keys ()))),
62+ headers = ';' .join (sorted (headers .keys ())),
63+ sign = sign
64+ )
65+ r .headers = http_header
66+ logger .debug ("sign_key" + str (sign_key ))
67+ logger .debug (r .headers ['Authorization' ])
68+
69+ logger .debug ("request headers: " + str (r .headers ))
70+ return r
71+
72+
73+ if __name__ == "__main__" :
74+ url = 'http://lewzylu01-1252448703.cn-south.myqcloud.com/a.txt'
7475
0 commit comments