Skip to content

Commit db0bcc2

Browse files
dt3310321tiedu
andauthored
S3 (#165)
* add get_object_url * modify ut * fix autocrlf Co-authored-by: tiedu <tiedu@tencent.com>
1 parent 2b5e438 commit db0bcc2

File tree

4 files changed

+4724
-4733
lines changed

4 files changed

+4724
-4733
lines changed

qcloud_cos/__init__.py

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1-
from .cos_client import CosS3Client
2-
from .cos_client import CosConfig
3-
from .cos_exception import CosServiceError
4-
from .cos_exception import CosClientError
5-
from .cos_auth import CosS3Auth
6-
from .cos_comm import get_date
7-
8-
import logging
9-
10-
try:
11-
from logging import NullHandler
12-
except ImportError:
13-
class NullHandler(logging.Handler):
14-
def emit(self, record):
15-
pass
16-
17-
logging.getLogger(__name__).addHandler(NullHandler())
1+
from .cos_client import CosS3Client
2+
from .cos_client import CosConfig
3+
from .cos_exception import CosServiceError
4+
from .cos_exception import CosClientError
5+
from .cos_auth import CosS3Auth
6+
from .cos_comm import get_date
7+
8+
import logging
9+
10+
try:
11+
from logging import NullHandler
12+
except ImportError:
13+
class NullHandler(logging.Handler):
14+
def emit(self, record):
15+
pass
16+
17+
logging.getLogger(__name__).addHandler(NullHandler())

qcloud_cos/cos_auth.py

Lines changed: 138 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -1,138 +1,138 @@
1-
# -*- coding: utf-8 -*-
2-
3-
from six.moves.urllib.parse import quote, unquote, urlparse, urlencode
4-
import hmac
5-
import time
6-
import hashlib
7-
import logging
8-
from requests.auth import AuthBase
9-
from .cos_comm import to_unicode, to_bytes, to_str
10-
logger = logging.getLogger(__name__)
11-
12-
13-
def filter_headers(data):
14-
"""只设置host content-type 还有x开头的头部.
15-
16-
:param data(dict): 所有的头部信息.
17-
:return(dict): 计算进签名的头部.
18-
"""
19-
valid_headers = [
20-
"cache-control",
21-
"content-disposition",
22-
"content-encoding",
23-
"content-type",
24-
"expires",
25-
"content-md5",
26-
"content-length",
27-
"host"
28-
]
29-
headers = {}
30-
for i in data:
31-
if str.lower(i) in valid_headers or str.lower(i[0]) == "x":
32-
headers[i] = data[i]
33-
return headers
34-
35-
36-
class CosS3Auth(AuthBase):
37-
38-
def __init__(self, conf, key=None, params={}, expire=10000):
39-
self._secret_id = conf._secret_id
40-
self._secret_key = conf._secret_key
41-
self._anonymous = conf._anonymous
42-
self._expire = expire
43-
self._params = params
44-
if key:
45-
key = to_unicode(key)
46-
if key[0] == u'/':
47-
self._path = key
48-
else:
49-
self._path = u'/' + key
50-
else:
51-
self._path = u'/'
52-
53-
def __call__(self, r):
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([(quote(to_bytes(to_str(k)), '-_.~').lower(), quote(to_bytes(to_str(v)), '-_.~')) for k, v in headers.items()]) # headers中的key转换为小写,value进行encode
59-
uri_params = dict([(quote(to_bytes(to_str(k)), '-_.~').lower(), quote(to_bytes(to_str(v)), '-_.~')) for k, v in uri_params.items()])
60-
format_str = u"{method}\n{host}\n{params}\n{headers}\n".format(
61-
method=r.method.lower(),
62-
host=path,
63-
params='&'.join(map(lambda tupl: "%s=%s" % (tupl[0], tupl[1]), sorted(uri_params.items()))),
64-
headers='&'.join(map(lambda tupl: "%s=%s" % (tupl[0], tupl[1]), sorted(headers.items())))
65-
)
66-
logger.debug("format str: " + format_str)
67-
68-
start_sign_time = int(time.time())
69-
sign_time = "{bg_time};{ed_time}".format(bg_time=start_sign_time-60, ed_time=start_sign_time+self._expire)
70-
sha1 = hashlib.sha1()
71-
sha1.update(to_bytes(format_str))
72-
73-
str_to_sign = "sha1\n{time}\n{sha1}\n".format(time=sign_time, sha1=sha1.hexdigest())
74-
logger.debug('str_to_sign: ' + str(str_to_sign))
75-
sign_key = hmac.new(to_bytes(self._secret_key), to_bytes(sign_time), hashlib.sha1).hexdigest()
76-
sign = hmac.new(to_bytes(sign_key), to_bytes(str_to_sign), hashlib.sha1).hexdigest()
77-
logger.debug('sign_key: ' + str(sign_key))
78-
logger.debug('sign: ' + str(sign))
79-
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}"
80-
81-
r.headers['Authorization'] = sign_tpl.format(
82-
ak=self._secret_id,
83-
sign_time=sign_time,
84-
key_time=sign_time,
85-
params=';'.join(sorted(uri_params.keys())),
86-
headers=';'.join(sorted(headers.keys())),
87-
sign=sign
88-
)
89-
if self._anonymous:
90-
r.headers['Authorization'] = ""
91-
logger.debug("sign_key" + str(sign_key))
92-
logger.debug(r.headers['Authorization'])
93-
logger.debug("request headers: " + str(r.headers))
94-
return r
95-
96-
97-
class CosRtmpAuth(AuthBase):
98-
99-
def __init__(self, conf, bucket=None, channel=None, params={}, expire=10000):
100-
self._secret_id = conf._secret_id
101-
self._secret_key = conf._secret_key
102-
self._token = conf._token
103-
self._anonymous = conf._anonymous
104-
self._expire = expire
105-
self._params = params
106-
if self._token:
107-
self._params['q-token'] = self._token
108-
self._path = u'/' + bucket + u'/' + channel
109-
110-
def get_rtmp_sign(self):
111-
# get rtmp string
112-
canonicalized_param = ''
113-
for k, v in self._params.iteritems():
114-
canonicalized_param += '{key}={value}&'.format(key=k, value=v)
115-
canonicalized_param = canonicalized_param.rstrip('&')
116-
rtmp_str = u"{path}\n{params}\n".format(path=self._path, params=canonicalized_param)
117-
logger.debug("rtmp str: " + rtmp_str)
118-
119-
sha1 = hashlib.sha1()
120-
sha1.update(to_bytes(rtmp_str))
121-
# get time
122-
sign_time = int(time.time())
123-
sign_time_str = "{start_time};{end_time}".format(start_time=sign_time-60, end_time=sign_time+self._expire)
124-
str_to_sign = "sha1\n{time}\n{sha1}\n".format(time=sign_time_str, sha1=sha1.hexdigest())
125-
logger.debug('str_to_sign: ' + str(str_to_sign))
126-
# get sinature
127-
signature = hmac.new(to_bytes(self._secret_key), to_bytes(str_to_sign), hashlib.sha1).hexdigest()
128-
logger.debug('signature: ' + str(signature))
129-
rtmp_sign = "q-sign-algorithm=sha1&q-ak={ak}&q-sign-time={sign_time}&q-key-time={key_time}&q-signature={sign}".format(
130-
ak=self._secret_id, sign_time=sign_time_str, key_time=sign_time_str, sign=signature)
131-
if canonicalized_param != '':
132-
return rtmp_sign + "&{params}".format(params=canonicalized_param)
133-
else:
134-
return rtmp_sign
135-
136-
137-
if __name__ == "__main__":
138-
pass
1+
# -*- coding: utf-8 -*-
2+
3+
from six.moves.urllib.parse import quote, unquote, urlparse, urlencode
4+
import hmac
5+
import time
6+
import hashlib
7+
import logging
8+
from requests.auth import AuthBase
9+
from .cos_comm import to_unicode, to_bytes, to_str
10+
logger = logging.getLogger(__name__)
11+
12+
13+
def filter_headers(data):
14+
"""只设置host content-type 还有x开头的头部.
15+
16+
:param data(dict): 所有的头部信息.
17+
:return(dict): 计算进签名的头部.
18+
"""
19+
valid_headers = [
20+
"cache-control",
21+
"content-disposition",
22+
"content-encoding",
23+
"content-type",
24+
"expires",
25+
"content-md5",
26+
"content-length",
27+
"host"
28+
]
29+
headers = {}
30+
for i in data:
31+
if str.lower(i) in valid_headers or str.lower(i[0]) == "x":
32+
headers[i] = data[i]
33+
return headers
34+
35+
36+
class CosS3Auth(AuthBase):
37+
38+
def __init__(self, conf, key=None, params={}, expire=10000):
39+
self._secret_id = conf._secret_id
40+
self._secret_key = conf._secret_key
41+
self._anonymous = conf._anonymous
42+
self._expire = expire
43+
self._params = params
44+
if key:
45+
key = to_unicode(key)
46+
if key[0] == u'/':
47+
self._path = key
48+
else:
49+
self._path = u'/' + key
50+
else:
51+
self._path = u'/'
52+
53+
def __call__(self, r):
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([(quote(to_bytes(to_str(k)), '-_.~').lower(), quote(to_bytes(to_str(v)), '-_.~')) for k, v in headers.items()]) # headers中的key转换为小写,value进行encode
59+
uri_params = dict([(quote(to_bytes(to_str(k)), '-_.~').lower(), quote(to_bytes(to_str(v)), '-_.~')) for k, v in uri_params.items()])
60+
format_str = u"{method}\n{host}\n{params}\n{headers}\n".format(
61+
method=r.method.lower(),
62+
host=path,
63+
params='&'.join(map(lambda tupl: "%s=%s" % (tupl[0], tupl[1]), sorted(uri_params.items()))),
64+
headers='&'.join(map(lambda tupl: "%s=%s" % (tupl[0], tupl[1]), sorted(headers.items())))
65+
)
66+
logger.debug("format str: " + format_str)
67+
68+
start_sign_time = int(time.time())
69+
sign_time = "{bg_time};{ed_time}".format(bg_time=start_sign_time-60, ed_time=start_sign_time+self._expire)
70+
sha1 = hashlib.sha1()
71+
sha1.update(to_bytes(format_str))
72+
73+
str_to_sign = "sha1\n{time}\n{sha1}\n".format(time=sign_time, sha1=sha1.hexdigest())
74+
logger.debug('str_to_sign: ' + str(str_to_sign))
75+
sign_key = hmac.new(to_bytes(self._secret_key), to_bytes(sign_time), hashlib.sha1).hexdigest()
76+
sign = hmac.new(to_bytes(sign_key), to_bytes(str_to_sign), hashlib.sha1).hexdigest()
77+
logger.debug('sign_key: ' + str(sign_key))
78+
logger.debug('sign: ' + str(sign))
79+
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}"
80+
81+
r.headers['Authorization'] = sign_tpl.format(
82+
ak=self._secret_id,
83+
sign_time=sign_time,
84+
key_time=sign_time,
85+
params=';'.join(sorted(uri_params.keys())),
86+
headers=';'.join(sorted(headers.keys())),
87+
sign=sign
88+
)
89+
if self._anonymous:
90+
r.headers['Authorization'] = ""
91+
logger.debug("sign_key" + str(sign_key))
92+
logger.debug(r.headers['Authorization'])
93+
logger.debug("request headers: " + str(r.headers))
94+
return r
95+
96+
97+
class CosRtmpAuth(AuthBase):
98+
99+
def __init__(self, conf, bucket=None, channel=None, params={}, expire=10000):
100+
self._secret_id = conf._secret_id
101+
self._secret_key = conf._secret_key
102+
self._token = conf._token
103+
self._anonymous = conf._anonymous
104+
self._expire = expire
105+
self._params = params
106+
if self._token:
107+
self._params['q-token'] = self._token
108+
self._path = u'/' + bucket + u'/' + channel
109+
110+
def get_rtmp_sign(self):
111+
# get rtmp string
112+
canonicalized_param = ''
113+
for k, v in self._params.iteritems():
114+
canonicalized_param += '{key}={value}&'.format(key=k, value=v)
115+
canonicalized_param = canonicalized_param.rstrip('&')
116+
rtmp_str = u"{path}\n{params}\n".format(path=self._path, params=canonicalized_param)
117+
logger.debug("rtmp str: " + rtmp_str)
118+
119+
sha1 = hashlib.sha1()
120+
sha1.update(to_bytes(rtmp_str))
121+
# get time
122+
sign_time = int(time.time())
123+
sign_time_str = "{start_time};{end_time}".format(start_time=sign_time-60, end_time=sign_time+self._expire)
124+
str_to_sign = "sha1\n{time}\n{sha1}\n".format(time=sign_time_str, sha1=sha1.hexdigest())
125+
logger.debug('str_to_sign: ' + str(str_to_sign))
126+
# get sinature
127+
signature = hmac.new(to_bytes(self._secret_key), to_bytes(str_to_sign), hashlib.sha1).hexdigest()
128+
logger.debug('signature: ' + str(signature))
129+
rtmp_sign = "q-sign-algorithm=sha1&q-ak={ak}&q-sign-time={sign_time}&q-key-time={key_time}&q-signature={sign}".format(
130+
ak=self._secret_id, sign_time=sign_time_str, key_time=sign_time_str, sign=signature)
131+
if canonicalized_param != '':
132+
return rtmp_sign + "&{params}".format(params=canonicalized_param)
133+
else:
134+
return rtmp_sign
135+
136+
137+
if __name__ == "__main__":
138+
pass

0 commit comments

Comments
 (0)