Skip to content

Commit 20d9e94

Browse files
zhy1985555yuniszhang
andauthored
add host to the string to sign (#172)
* support redirect config * set allow_redirects default value to false * add host to str_to_sign * add host to the string to sign * add host to the string to sign * add host to the string to sign * add host to the string to sign * url = u"{scheme}://{bucket}.{endpoint}/{ * add host to the string to sign * add host to the string to sign Co-authored-by: yuniszhang <yuniszhang@tencent.com>
1 parent c354d38 commit 20d9e94

File tree

2 files changed

+37
-8
lines changed

2 files changed

+37
-8
lines changed

qcloud_cos/cos_auth.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,19 @@ def filter_headers(data):
3636

3737
class CosS3Auth(AuthBase):
3838

39-
def __init__(self, conf, key=None, params={}, expire=10000):
39+
def __init__(self, conf, key=None, params={}, expire=10000, sign_host=None):
4040
self._secret_id = conf._secret_id
4141
self._secret_key = conf._secret_key
4242
self._anonymous = conf._anonymous
4343
self._expire = expire
4444
self._params = params
45+
46+
# 如果API指定了是否签名host,则以具体API为准,如果未指定则以配置为准
47+
if sign_host is not None:
48+
self._sign_host = bool(sign_host)
49+
else:
50+
self._sign_host = conf._sign_host
51+
4552
if key:
4653
key = to_unicode(key)
4754
if key[0] == u'/':
@@ -55,6 +62,23 @@ def __call__(self, r):
5562
path = self._path
5663
uri_params = self._params
5764
headers = filter_headers(r.headers)
65+
66+
# 如果headers中不包含host头域,则从url中提取host,并且加入签名计算
67+
if self._sign_host:
68+
69+
# 判断headers中是否包含host头域
70+
contain_host = False
71+
for i in headers:
72+
if str.lower(i) == "host": # 兼容host/Host/HOST等
73+
contain_host = True
74+
break
75+
76+
# 从url中提取host
77+
if not contain_host:
78+
url_parsed = urlparse(r.url)
79+
if url_parsed.hostname is not None:
80+
headers["host"] = url_parsed.hostname
81+
5882
# reserved keywords in headers urlencode are -_.~, notice that / should be encoded and space should not be encoded to plus sign(+)
5983
headers = dict([(quote(to_bytes(to_str(k)), '-_.~').lower(), quote(to_bytes(to_str(v)), '-_.~')) for k, v in
6084
headers.items()]) # headers中的key转换为小写,value进行encode

qcloud_cos/cos_client.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class CosConfig(object):
3939
def __init__(self, Appid=None, Region=None, SecretId=None, SecretKey=None, Token=None, Scheme=None, Timeout=None,
4040
Access_id=None, Access_key=None, Secret_id=None, Secret_key=None, Endpoint=None, IP=None, Port=None,
4141
Anonymous=None, UA=None, Proxies=None, Domain=None, ServiceDomain=None, PoolConnections=10,
42-
PoolMaxSize=10, AllowRedirects=False):
42+
PoolMaxSize=10, AllowRedirects=False, SignHost=True):
4343
"""初始化,保存用户的信息
4444
4545
:param Appid(string): 用户APPID.
@@ -64,6 +64,7 @@ def __init__(self, Appid=None, Region=None, SecretId=None, SecretKey=None, Token
6464
:param PoolConnections(int): 连接池个数
6565
:param PoolMaxSize(int): 连接池中最大连接数
6666
:param AllowRedirects(bool): 是否重定向
67+
:param SignHost(bool): 是否将host算入签名
6768
"""
6869
self._appid = to_unicode(Appid)
6970
self._token = to_unicode(Token)
@@ -80,6 +81,7 @@ def __init__(self, Appid=None, Region=None, SecretId=None, SecretKey=None, Token
8081
self._pool_connections = PoolConnections
8182
self._pool_maxsize = PoolMaxSize
8283
self._allow_redirects = AllowRedirects
84+
self._sign_host = SignHost
8385

8486
if self._domain is None:
8587
self._endpoint = format_endpoint(Endpoint, Region)
@@ -201,7 +203,7 @@ def get_conf(self):
201203
"""获取配置"""
202204
return self._conf
203205

204-
def get_auth(self, Method, Bucket, Key, Expired=300, Headers={}, Params={}):
206+
def get_auth(self, Method, Bucket, Key, Expired=300, Headers={}, Params={}, SignHost=None):
205207
"""获取签名
206208
207209
:param Method(string): http method,如'PUT','GET'.
@@ -210,6 +212,7 @@ def get_auth(self, Method, Bucket, Key, Expired=300, Headers={}, Params={}):
210212
:param Expired(int): 签名有效时间,单位为s.
211213
:param headers(dict): 签名中的http headers.
212214
:param params(dict): 签名中的http params.
215+
:param SignHost(bool): 是否将host算入签名.
213216
:return (string): 计算出的V5签名.
214217
215218
.. code-block:: python
@@ -229,7 +232,7 @@ def get_auth(self, Method, Bucket, Key, Expired=300, Headers={}, Params={}):
229232
"""
230233
url = self._conf.uri(bucket=Bucket, path=Key)
231234
r = Request(Method, url, headers=Headers, params=Params)
232-
auth = CosS3Auth(self._conf, Key, Params, Expired)
235+
auth = CosS3Auth(self._conf, Key, Params, Expired, SignHost)
233236
return auth(r).headers['Authorization']
234237

235238
def send_request(self, method, url, bucket, timeout=30, cos_request=True, **kwargs):
@@ -491,7 +494,7 @@ def get_object_sensitive_content_recognition(self, Bucket, Key, DetectType, Inte
491494

492495
return data
493496

494-
def get_presigned_url(self, Bucket, Key, Method, Expired=300, Params={}, Headers={}):
497+
def get_presigned_url(self, Bucket, Key, Method, Expired=300, Params={}, Headers={}, SignHost=None):
495498
"""生成预签名的url
496499
497500
:param Bucket(string): 存储桶名称.
@@ -500,6 +503,7 @@ def get_presigned_url(self, Bucket, Key, Method, Expired=300, Params={}, Headers
500503
:param Expired(int): 签名过期时间.
501504
:param Params(dict): 签入签名的参数
502505
:param Headers(dict): 签入签名的头部
506+
:param SignHost(bool): 是否将host算入签名.
503507
:return(string): 预先签名的URL.
504508
505509
.. code-block:: python
@@ -514,21 +518,22 @@ def get_presigned_url(self, Bucket, Key, Method, Expired=300, Params={}, Headers
514518
)
515519
"""
516520
url = self._conf.uri(bucket=Bucket, path=Key)
517-
sign = self.get_auth(Method=Method, Bucket=Bucket, Key=Key, Expired=Expired, Headers=Headers, Params=Params)
521+
sign = self.get_auth(Method=Method, Bucket=Bucket, Key=Key, Expired=Expired, Headers=Headers, Params=Params, SignHost=SignHost)
518522
sign = urlencode(dict([item.split('=', 1) for item in sign.split('&')]))
519523
url = url + '?' + sign
520524
if Params:
521525
url = url + '&' + urlencode(Params)
522526
return url
523527

524-
def get_presigned_download_url(self, Bucket, Key, Expired=300, Params={}, Headers={}):
528+
def get_presigned_download_url(self, Bucket, Key, Expired=300, Params={}, Headers={}, SignHost=None):
525529
"""生成预签名的下载url
526530
527531
:param Bucket(string): 存储桶名称.
528532
:param Key(string): COS路径.
529533
:param Expired(int): 签名过期时间.
530534
:param Params(dict): 签入签名的参数
531535
:param Headers(dict): 签入签名的头部
536+
:param SignHost(bool): 是否将host算入签名.
532537
:return(string): 预先签名的下载URL.
533538
534539
.. code-block:: python
@@ -541,7 +546,7 @@ def get_presigned_download_url(self, Bucket, Key, Expired=300, Params={}, Header
541546
Key='test.txt'
542547
)
543548
"""
544-
return self.get_presigned_url(Bucket, Key, 'GET', Expired, Params, Headers)
549+
return self.get_presigned_url(Bucket, Key, 'GET', Expired, Params, Headers, SignHost)
545550

546551
def get_object_url(self, Bucket, Key):
547552
"""生成对象访问的url

0 commit comments

Comments
 (0)