2525sys .setdefaultencoding ('utf-8' )
2626maplist = {
2727 'ContentLength' : 'Content-Length' ,
28- 'ContentType' : 'Content-Type' ,
2928 'ContentMD5' : 'Content-MD5' ,
29+ 'ContentType' : 'Content-Type' ,
3030 'CacheControl' : 'Cache-Control' ,
3131 'ContentDisposition' : 'Content-Disposition' ,
3232 'ContentEncoding' : 'Content-Encoding' ,
33+ 'ContentLanguage' : 'Content-Language' ,
3334 'Expires' : 'Expires' ,
35+ 'ResponseContentType' : 'response-content-type' ,
36+ 'ResponseContentLanguage' : 'response-content-language' ,
37+ 'ResponseExpires' : 'response-expires' ,
38+ 'ResponseCacheControl' : 'response-cache-control' ,
39+ 'ResponseContentDisposition' : 'response-content-disposition' ,
40+ 'ResponseContentEncoding' : 'response-content-encoding' ,
3441 'Metadata' : 'Metadata' ,
3542 'ACL' : 'x-cos-acl' ,
3643 'GrantFullControl' : 'x-cos-grant-full-control' ,
3744 'GrantWrite' : 'x-cos-grant-write' ,
3845 'GrantRead' : 'x-cos-grant-read' ,
3946 'StorageClass' : 'x-cos-storage-class' ,
40- 'EncodingType' : 'encoding-type'
47+ 'Range' : 'Range' ,
48+ 'IfMatch' : 'If-Match' ,
49+ 'IfNoneMatch' : 'If-None-Match' ,
50+ 'IfModifiedSince' : 'If-Modified-Since' ,
51+ 'IfUnmodifiedSince' : 'If-Unmodified-Since' ,
52+ 'VersionId' : 'x-cos-version-id' ,
4153 }
4254
4355
@@ -109,11 +121,39 @@ def mapped(headers):
109121 return _headers
110122
111123
124+ def format_region (region ):
125+ if region .find ('cos.' ) != - 1 :
126+ return region # 传入cos.ap-beijing-1这样显示加上cos.的region
127+ if region == 'cn-north' or region == 'cn-south' or region == 'cn-east' or region == 'cn-south-2' or region == 'cn-southwest' or region == 'sg' :
128+ return region # 老域名不能加cos.
129+ # 支持v4域名映射到v5
130+ if region == 'cossh' :
131+ return 'cos.ap-shanghai'
132+ if region == 'cosgz' :
133+ return 'cos.ap-guangzhou'
134+ if region == 'cosbj' :
135+ return 'cos.ap-beijing'
136+ if region == 'costj' :
137+ return 'cos.ap-beijing-1'
138+ if region == 'coscd' :
139+ return 'cos.ap-chengdu'
140+ if region == 'cossgp' :
141+ return 'cos.ap-singapore'
142+ if region == 'coshk' :
143+ return 'cos.ap-hongkong'
144+ if region == 'cosca' :
145+ return 'cos.na-toronto'
146+ if region == 'cosger' :
147+ return 'cos.eu-frankfurt'
148+
149+ return 'cos.' + region # 新域名加上cos.
150+
151+
112152class CosConfig (object ):
113153 """config类,保存用户相关信息"""
114154 def __init__ (self , Appid , Region , Access_id , Access_key , Token = None ):
115155 self ._appid = Appid
116- self ._region = Region
156+ self ._region = format_region ( Region )
117157 self ._access_id = Access_id
118158 self ._access_key = Access_key
119159 self ._token = Token
@@ -126,14 +166,14 @@ def uri(self, bucket, path=None):
126166 if path :
127167 if path [0 ] == '/' :
128168 path = path [1 :]
129- url = u"http://{bucket}-{uid}.cos. {region}.myqcloud.com/{path}" .format (
169+ url = u"http://{bucket}-{uid}.{region}.myqcloud.com/{path}" .format (
130170 bucket = to_unicode (bucket ),
131171 uid = self ._appid ,
132172 region = self ._region ,
133173 path = to_unicode (path )
134174 )
135175 else :
136- url = u"http://{bucket}-{uid}.cos. {region}.myqcloud.com" .format (
176+ url = u"http://{bucket}-{uid}.{region}.myqcloud.com" .format (
137177 bucket = to_unicode (bucket ),
138178 uid = self ._appid ,
139179 region = self ._region
@@ -246,7 +286,7 @@ def get_presigned_download_url(self, Bucket, Key, Expired=300):
246286 """生成预签名的下载url"""
247287 url = self ._conf .uri (bucket = Bucket , path = Key )
248288 sign = self .get_auth (Method = 'GET' , Bucket = Bucket , Key = Key , Expired = 300 )
249- url = url + '?sign=' + urllib .quote (sign )
289+ url = urllib . quote ( url . encode ( 'utf8' ), ':/' ) + '?sign=' + urllib .quote (sign )
250290 return url
251291
252292 def delete_object (self , Bucket , Key , ** kwargs ):
@@ -311,6 +351,11 @@ def copy_object(self, Bucket, Key, CopySource, CopyStatus='Copy', **kwargs):
311351 def create_multipart_upload (self , Bucket , Key , ** kwargs ):
312352 """创建分片上传,适用于大文件上传"""
313353 headers = mapped (kwargs )
354+ if 'Metadata' in headers .keys ():
355+ for i in headers ['Metadata' ].keys ():
356+ headers [i ] = headers ['Metadata' ][i ]
357+ headers .pop ('Metadata' )
358+
314359 url = self ._conf .uri (bucket = Bucket , path = Key + "?uploads" )
315360 logger .info ("create multipart upload, url=:{url} ,headers=:{headers}" .format (
316361 url = url ,
@@ -374,18 +419,25 @@ def abort_multipart_upload(self, Bucket, Key, UploadId, **kwargs):
374419 headers = headers )
375420 return None
376421
377- def list_parts (self , Bucket , Key , UploadId , ** kwargs ):
422+ def list_parts (self , Bucket , Key , UploadId , EncodingType = 'url' , MaxParts = 1000 , PartNumberMarker = 0 , ** kwargs ):
378423 """列出已上传的分片"""
379424 headers = mapped (kwargs )
380- url = self ._conf .uri (bucket = Bucket , path = Key + "?uploadId={UploadId}" .format (UploadId = UploadId ))
425+ params = {
426+ 'uploadId' : UploadId ,
427+ 'part-number-marker' : PartNumberMarker ,
428+ 'max-parts' : MaxParts ,
429+ 'encoding-type' : EncodingType }
430+
431+ url = self ._conf .uri (bucket = Bucket , path = Key )
381432 logger .info ("list multipart upload, url=:{url} ,headers=:{headers}" .format (
382433 url = url ,
383434 headers = headers ))
384435 rt = self .send_request (
385436 method = 'GET' ,
386437 url = url ,
387438 auth = CosS3Auth (self ._conf ._access_id , self ._conf ._access_key ),
388- headers = headers )
439+ headers = headers ,
440+ params = params )
389441 data = xml_to_dict (rt .text )
390442 if 'Part' in data .keys () and isinstance (data ['Part' ], dict ): # 只有一个part,将dict转为list,保持一致
391443 lst = []
@@ -455,7 +507,7 @@ def delete_bucket(self, Bucket, **kwargs):
455507 headers = headers )
456508 return None
457509
458- def list_objects (self , Bucket , Delimiter = "" , Marker = "" , MaxKeys = 1000 , Prefix = "" , ** kwargs ):
510+ def list_objects (self , Bucket , Delimiter = "" , Marker = "" , MaxKeys = 1000 , Prefix = "" , EncodingType = "url" , ** kwargs ):
459511 """获取文件列表"""
460512 headers = mapped (kwargs )
461513 url = self ._conf .uri (bucket = Bucket )
@@ -466,7 +518,8 @@ def list_objects(self, Bucket, Delimiter="", Marker="", MaxKeys=1000, Prefix="",
466518 'delimiter' : Delimiter ,
467519 'marker' : Marker ,
468520 'max-keys' : MaxKeys ,
469- 'prefix' : Prefix }
521+ 'prefix' : Prefix ,
522+ 'encoding-type' : EncodingType }
470523 rt = self .send_request (
471524 method = 'GET' ,
472525 url = url ,
0 commit comments