Merge pull request #2155 from gtmanfred/master
set default status for s3 posts and add success_action_redirect support
This commit is contained in:
commit
4575f359c1
@ -5,9 +5,10 @@ import sys
|
||||
|
||||
import six
|
||||
from botocore.awsrequest import AWSPreparedRequest
|
||||
from werkzeug.wrappers import Request
|
||||
|
||||
from moto.core.utils import str_to_rfc_1123_datetime, py2_strip_unicode_keys
|
||||
from six.moves.urllib.parse import parse_qs, urlparse, unquote
|
||||
from six.moves.urllib.parse import parse_qs, urlparse, unquote, parse_qsl
|
||||
|
||||
import xmltodict
|
||||
|
||||
@ -777,6 +778,7 @@ class ResponseObject(_TemplateEnvironmentMixin, ActionAuthenticatorMixin):
|
||||
return 409, {}, template.render(bucket=removed_bucket)
|
||||
|
||||
def _bucket_response_post(self, request, body, bucket_name):
|
||||
response_headers = {}
|
||||
if not request.headers.get("Content-Length"):
|
||||
return 411, {}, "Content-Length required"
|
||||
|
||||
@ -795,14 +797,18 @@ class ResponseObject(_TemplateEnvironmentMixin, ActionAuthenticatorMixin):
|
||||
if hasattr(request, "form"):
|
||||
# Not HTTPretty
|
||||
form = request.form
|
||||
elif request.headers.get("Content-Type").startswith("multipart/form-data"):
|
||||
request = Request.from_values(
|
||||
input_stream=six.BytesIO(request.body),
|
||||
content_length=request.headers["Content-Length"],
|
||||
content_type=request.headers["Content-Type"],
|
||||
method="POST",
|
||||
)
|
||||
form = request.form
|
||||
else:
|
||||
# HTTPretty, build new form object
|
||||
body = body.decode()
|
||||
|
||||
form = {}
|
||||
for kv in body.split("&"):
|
||||
k, v = kv.split("=")
|
||||
form[k] = v
|
||||
form = dict(parse_qsl(body))
|
||||
|
||||
key = form["key"]
|
||||
if "file" in form:
|
||||
@ -810,13 +816,23 @@ class ResponseObject(_TemplateEnvironmentMixin, ActionAuthenticatorMixin):
|
||||
else:
|
||||
f = request.files["file"].stream.read()
|
||||
|
||||
if "success_action_redirect" in form:
|
||||
response_headers["Location"] = form["success_action_redirect"]
|
||||
|
||||
if "success_action_status" in form:
|
||||
status_code = form["success_action_status"]
|
||||
elif "success_action_redirect" in form:
|
||||
status_code = 303
|
||||
else:
|
||||
status_code = 204
|
||||
|
||||
new_key = self.backend.set_key(bucket_name, key, f)
|
||||
|
||||
# Metadata
|
||||
metadata = metadata_from_headers(form)
|
||||
new_key.set_metadata(metadata)
|
||||
|
||||
return 200, {}, ""
|
||||
return status_code, response_headers, ""
|
||||
|
||||
@staticmethod
|
||||
def _get_path(request):
|
||||
|
@ -14,6 +14,7 @@ from io import BytesIO
|
||||
import mimetypes
|
||||
import zlib
|
||||
import pickle
|
||||
import uuid
|
||||
|
||||
import json
|
||||
import boto
|
||||
@ -4428,3 +4429,41 @@ def test_s3_config_dict():
|
||||
assert not logging_bucket["supplementaryConfiguration"].get(
|
||||
"BucketTaggingConfiguration"
|
||||
)
|
||||
|
||||
|
||||
@mock_s3
|
||||
def test_creating_presigned_post():
|
||||
bucket = "presigned-test"
|
||||
s3 = boto3.client("s3", region_name="us-east-1")
|
||||
s3.create_bucket(Bucket=bucket)
|
||||
success_url = "http://localhost/completed"
|
||||
fdata = b"test data\n"
|
||||
file_uid = uuid.uuid4()
|
||||
conditions = [
|
||||
{"Content-Type": "text/plain"},
|
||||
{"x-amz-server-side-encryption": "AES256"},
|
||||
{"success_action_redirect": success_url},
|
||||
]
|
||||
conditions.append(["content-length-range", 1, 30])
|
||||
data = s3.generate_presigned_post(
|
||||
Bucket=bucket,
|
||||
Key="{file_uid}.txt".format(file_uid=file_uid),
|
||||
Fields={
|
||||
"content-type": "text/plain",
|
||||
"success_action_redirect": success_url,
|
||||
"x-amz-server-side-encryption": "AES256",
|
||||
},
|
||||
Conditions=conditions,
|
||||
ExpiresIn=1000,
|
||||
)
|
||||
resp = requests.post(
|
||||
data["url"], data=data["fields"], files={"file": fdata}, allow_redirects=False
|
||||
)
|
||||
assert resp.headers["Location"] == success_url
|
||||
assert resp.status_code == 303
|
||||
assert (
|
||||
s3.get_object(Bucket=bucket, Key="{file_uid}.txt".format(file_uid=file_uid))[
|
||||
"Body"
|
||||
].read()
|
||||
== fdata
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user