|
11 | 11 | # ANY KIND, either express or implied. See the License for the specific |
12 | 12 | # language governing permissions and limitations under the License. |
13 | 13 | import datetime |
| 14 | +import io |
14 | 15 | import re |
15 | 16 |
|
16 | 17 | import pytest |
|
43 | 44 | DATE = datetime.datetime(2021, 8, 27, 0, 0, 0, tzinfo=datetime.timezone.utc) |
44 | 45 |
|
45 | 46 |
|
| 47 | +class NonSeekableStream(io.RawIOBase): |
| 48 | + def __init__(self, data): |
| 49 | + self._data = data |
| 50 | + self._pos = 0 |
| 51 | + |
| 52 | + def read(self, size=-1): |
| 53 | + if size == -1: |
| 54 | + size = len(self._data) - self._pos |
| 55 | + chunk = self._data[self._pos : self._pos + size] |
| 56 | + self._pos += len(chunk) |
| 57 | + return chunk |
| 58 | + |
| 59 | + def readable(self): |
| 60 | + return True |
| 61 | + |
| 62 | + |
46 | 63 | class TestS3BucketValidation(unittest.TestCase): |
47 | 64 | def test_invalid_bucket_name_raises_error(self): |
48 | 65 | session = botocore.session.get_session() |
@@ -1550,6 +1567,27 @@ def test_trailing_checksum_set_with_content_length_removes_header(self): |
1550 | 1567 | self.assertIn(b"x-amz-checksum-crc32:eCQEmA==", body) |
1551 | 1568 | self.assertNotIn("Content-Length", sent_headers) |
1552 | 1569 |
|
| 1570 | + def test_trailing_checksum_non_seekable_body_uses_content_length(self): |
| 1571 | + with self.http_stubber: |
| 1572 | + self.client.put_object( |
| 1573 | + Bucket="foo", |
| 1574 | + Key="bar", |
| 1575 | + Body=NonSeekableStream(b"hello world"), |
| 1576 | + ContentLength=11, |
| 1577 | + ) |
| 1578 | + sent_headers = self.get_sent_headers() |
| 1579 | + self.assertEqual(sent_headers["Content-Encoding"], b"aws-chunked") |
| 1580 | + self.assertEqual(sent_headers["Transfer-Encoding"], b"chunked") |
| 1581 | + self.assertEqual( |
| 1582 | + sent_headers["X-Amz-Trailer"], b"x-amz-checksum-crc32" |
| 1583 | + ) |
| 1584 | + self.assertEqual(sent_headers["X-Amz-Decoded-Content-Length"], b"11") |
| 1585 | + self.assertEqual( |
| 1586 | + sent_headers["x-amz-content-sha256"], |
| 1587 | + b"STREAMING-UNSIGNED-PAYLOAD-TRAILER", |
| 1588 | + ) |
| 1589 | + self.assertNotIn("Content-Length", sent_headers) |
| 1590 | + |
1553 | 1591 | def test_trailing_checksum_set_empty_body(self): |
1554 | 1592 | with self.http_stubber: |
1555 | 1593 | self.client.put_object(Bucket="foo", Key="bar", Body="") |
|
0 commit comments