diff --git a/moto/s3/responses.py b/moto/s3/responses.py index 603571c0d..364ae4623 100644 --- a/moto/s3/responses.py +++ b/moto/s3/responses.py @@ -1092,6 +1092,11 @@ class ResponseObject(_TemplateEnvironmentMixin, ActionAuthenticatorMixin): else: # Flask server body = request.data + # when the data is being passed as a file + if request.files and not body: + for _, value in request.files.items(): + body = value.stream.read() + if body is None: body = b"" diff --git a/tests/test_s3/test_s3.py b/tests/test_s3/test_s3.py index 6622b2f41..078abfa3b 100644 --- a/tests/test_s3/test_s3.py +++ b/tests/test_s3/test_s3.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals import datetime import sys - +import os from boto3 import Session from six.moves.urllib.request import urlopen from six.moves.urllib.error import HTTPError @@ -1054,6 +1054,29 @@ def test_streaming_upload_from_file_to_presigned_url(): assert response.status_code == 200 +@mock_s3 +def test_multipart_upload_from_file_to_presigned_url(): + s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) + s3.create_bucket(Bucket="mybucket") + + params = {"Bucket": "mybucket", "Key": "file_upload"} + presigned_url = boto3.client("s3").generate_presigned_url( + "put_object", params, ExpiresIn=900 + ) + + file = open("text.txt", "w") + file.write("test") + file.close() + files = {"upload_file": open("text.txt", "rb")} + + requests.put(presigned_url, files=files) + resp = s3.get_object(Bucket="mybucket", Key="file_upload") + data = resp["Body"].read() + assert data == b"test" + # cleanup + os.remove("text.txt") + + @mock_s3 def test_s3_object_in_private_bucket(): s3 = boto3.resource("s3")