Skip to content

Upload fails using presigned post URL #608

@orientalperil

Description

@orientalperil

Describe the bug
I'm trying to upload a file using a presigned post URL. This code works on S3 and MinIO.

The response returns: <?xml version="1.0" encoding="UTF-8"?><Error><Code>MalformedPOSTRequest</Code></Error>

To Reproduce

import datetime

import boto3
import requests
from django.conf import settings

RETENTION = 'retention'
EXPIRE_FAST = 'expire_fast'
TEMP_MARKER = 'temp'

service = 's3'
region = 'us-east-1'
t = datetime.datetime.utcnow()
algorithm = 'AWS4-HMAC-SHA256'
credential_scope = '/'.join([t.strftime('%Y%m%d'), region, service, 'aws4_request'])

key = 'temp-22e063cd-4ed3-437c-87ac-2bc6e6f328d0/my_file.txt'


def get_tag_xml(key, value):
    return f"<Tagging><TagSet><Tag><Key>{key}</Key><Value>{value}</Value></Tag></TagSet></Tagging>"


conditions = [
    {"x-amz-algorithm": algorithm},
    {"x-amz-credential": credential_scope},
    {"x-amz-date": t.isoformat()},
    {"tagging": get_tag_xml(RETENTION, EXPIRE_FAST)},
    {"success_action_status": "201"},
    {"bucket": settings.AWS_STORAGE_BUCKET_NAME},
    ["starts-with", "$key", TEMP_MARKER],
]

fields = {
    "x-amz-algorithm": algorithm,
    "x-amz-credential": credential_scope,
    "x-amz-date": t.isoformat(),
    "tagging": get_tag_xml(RETENTION, EXPIRE_FAST),
    "success_action_status": "201",
}

client = boto3.client(
    service_name='s3',
    aws_access_key_id=settings.AWS_ACCESS_KEY_ID,
    aws_secret_access_key=settings.AWS_SECRET_ACCESS_KEY,
    endpoint_url=settings.AWS_S3_ENDPOINT_URL,  # http://127.0.0.1:6000
)

presigned = client.generate_presigned_post(
    settings.AWS_STORAGE_BUCKET_NAME,
    key,
    Fields=fields,
    Conditions=conditions,
    ExpiresIn=60*60,
)

# Demonstrate how another Python program can use the presigned URL to upload a file
object_name = 'my_file.txt'
with open(object_name, 'rb') as f:
    files = {'file': (object_name, f)}
    http_response = requests.post(presigned['url'], data=presigned['fields'], files=files)
print(f'File upload HTTP status code: {http_response.status_code}')
print(http_response.content)

Expected behavior
File should upload

Desktop (please complete the following information):

  • OS: macOS 15.6.1
  • Browser Chrome
  • Version rustfs 1.0.0-alpha.60

Additional context
Add any other context about the problem here.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions