Skip to content

Commit e2aaf4a

Browse files
author
yami
authored
Merge pull request #48 from aliyun/fix_upload_part_headers
add headers to upload_part()
2 parents 1688e1c + 6bb05a0 commit e2aaf4a

File tree

5 files changed

+43
-4
lines changed

5 files changed

+43
-4
lines changed

CHANGELOG.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@ OSS SDK for Python 版本记录
33

44
Python SDK的版本号遵循 `Semantic Versioning <http://semver.org/>`_ 规则。
55

6+
Version 2.2.2
7+
-------------
8+
9+
- 修复:upload_part接口加上headers参数
10+
11+
612
Version 2.2.1
713
-------------
814

oss2/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
__version__ = '2.2.1'
1+
__version__ = '2.2.2'
22

33
from . import models, exceptions
44

oss2/api.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,7 @@ def init_multipart_upload(self, key, headers=None):
635635
resp = self.__do_object('POST', key, params={'uploads': ''}, headers=headers)
636636
return self._parse_result(resp, xml_utils.parse_init_multipart_upload, InitMultipartUploadResult)
637637

638-
def upload_part(self, key, upload_id, part_number, data, progress_callback=None):
638+
def upload_part(self, key, upload_id, part_number, data, progress_callback=None, headers=None):
639639
"""上传一个分片。
640640
641641
:param str key: 待上传文件名,这个文件名要和 :func:`init_multipart_upload` 的文件名一致。
@@ -644,6 +644,9 @@ def upload_part(self, key, upload_id, part_number, data, progress_callback=None)
644644
:param data: 待上传数据。
645645
:param progress_callback: 用户指定进度回调函数。可以用来实现进度条等功能。参考 :ref:`progress_callback` 。
646646
647+
:param headers: 用户指定的HTTP头部。可以指定Content-MD5头部等
648+
:type headers: 可以是dict,建议是oss2.CaseInsensitiveDict
649+
647650
:return: :class:`PutObjectResult <oss2.models.PutObjectResult>`
648651
"""
649652
if progress_callback:
@@ -654,6 +657,7 @@ def upload_part(self, key, upload_id, part_number, data, progress_callback=None)
654657

655658
resp = self.__do_object('PUT', key,
656659
params={'uploadId': upload_id, 'partNumber': str(part_number)},
660+
headers=headers,
657661
data=data)
658662
result = PutObjectResult(resp)
659663

oss2/exceptions.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
OSS_REQUEST_ERROR_STATUS = -2
2424
OSS_INCONSISTENT_ERROR_STATUS = -3
2525

26+
2627
class OssError(Exception):
2728
def __init__(self, status, headers, body, details):
2829
#: HTTP 状态码
@@ -104,6 +105,11 @@ def __init__(self, status, headers, body, details):
104105
self.value = details.get('ArgumentValue')
105106

106107

108+
class InvalidDigest(ServerError):
109+
status = 400
110+
code = 'InvalidDigest'
111+
112+
107113
class InvalidObjectName(ServerError):
108114
status = 400
109115
code = 'InvalidObjectName'

tests/test_multipart.py

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,19 @@
77

88

99
class TestMultipart(OssTestCase):
10-
def test_multipart(self):
10+
def do_multipart_internal(self, do_md5):
1111
key = self.random_key()
1212
content = random_bytes(128 * 1024)
1313

1414
parts = []
1515
upload_id = self.bucket.init_multipart_upload(key).upload_id
1616

17-
result = self.bucket.upload_part(key, upload_id, 1, content)
17+
if do_md5:
18+
headers = {'Content-Md5': oss2.utils.content_md5(content)}
19+
else:
20+
headers = None
21+
22+
result = self.bucket.upload_part(key, upload_id, 1, content, headers=headers)
1823
parts.append(oss2.models.PartInfo(1, result.etag))
1924
self.assertTrue(result.crc is not None)
2025

@@ -23,6 +28,24 @@ def test_multipart(self):
2328
result = self.bucket.get_object(key)
2429
self.assertEqual(content, result.read())
2530

31+
def test_multipart(self):
32+
self.do_multipart_internal(False)
33+
34+
def test_upload_part_content_md5_good(self):
35+
self.do_multipart_internal(True)
36+
37+
def test_upload_part_content_md5_bad(self):
38+
key = self.random_key()
39+
content = random_bytes(128 * 1024)
40+
41+
parts = []
42+
upload_id = self.bucket.init_multipart_upload(key).upload_id
43+
44+
# construct a bad Content-Md5 by using 'content + content's Content-Md5
45+
headers = {'Content-Md5': oss2.utils.content_md5(content + content)}
46+
47+
self.assertRaises(oss2.exceptions.InvalidDigest, self.bucket.upload_part, key, upload_id, 1, content, headers=headers)
48+
2649
def test_progress(self):
2750
stats = {'previous': -1}
2851

0 commit comments

Comments
 (0)