Skip to content

Commit f72d92d

Browse files
authored
Merge pull request #16 from dt3310321/s3
SDK V2
2 parents 1b8a6e5 + 984a1ce commit f72d92d

File tree

8 files changed

+751
-114
lines changed

8 files changed

+751
-114
lines changed

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2017 腾讯云
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in
13+
all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
THE SOFTWARE.

README.rst

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ cos最新可用地域,参照https://www.qcloud.com/document/product/436/6224
2727
.. code:: python
2828
2929
# 设置用户属性, 包括appid, secret_id, secret_key, region
30-
appid = 100000 # 替换为用户的appid
31-
secret_id = u'xxxxxxxx' # 替换为用户的secret_id
32-
secret_key = u'xxxxxxx' # 替换为用户的secret_key
33-
  region = "ap-beiging-1"    # 替换为用户的region
34-
token = '' # 使用临时秘钥需要传入Token,默认为空,可不填
30+
appid = '100000' # 替换为用户的appid
31+
secret_id = 'xxxxxxxx' # 替换为用户的secret_id
32+
secret_key = 'xxxxxxx' # 替换为用户的secret_key
33+
  region = 'ap-beiging-1'   # 替换为用户的region
34+
token = '' # 使用临时秘钥需要传入Token,默认为空,可不填
3535
config = CosConfig(Appid=appid, Region=region, Access_id=secret_id, Access_key=secret_key, Token=token) #获取配置对象
3636
client = CosS3Client(config) #获取客户端对象
3737

qcloud_cos/cos_auth.py

Lines changed: 46 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,38 +11,61 @@
1111
logger = 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+
1438
class 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

Comments
 (0)