I'd like to add file size validation to our signed urls, making sure the client uploads a file of exactly the size I signed it with. However, when I do this :
"conditions": [
{"acl": "public-read"},
.... ,
["content-length-range", 1024, 1024]
]
For small files, it works.
But a bit larger files, for example 25mb, it results in EntityTooSmall error.
It starts working only if I set the minimum to 0 like this :
["content-length-range", 0, 1024]
But I want to enforce a specific file size, and not a range.
Does S3 not support exact file size match?
EDIT : Here's the full code I compiled in Python :
# Create an S3 client
s3 = boto3.client(
's3',
aws_access_key_id="...",
aws_secret_access_key="...",
region_name="sfo3",
endpoint_url="https://sfo3.digitaloceanspaces.com",
)
# Specify the bucket name
bucket_name = 'my_bucket'
# Specify the file name
file_name = 'SampleJPGImage_30mbmb.jpeg'
# Get the file size in bytes
file_size = os.path.getsize(file_name)
# Use the file size and content
print("File size:", file_size, "bytes") # Should be 30789588
# Specify the desired file size in bytes
file_size_min = file_size
file_size_max = file_size
# Sign the policy with your AWS secret key
signedPolicy = s3.generate_presigned_post(
Bucket=bucket_name,
Key=file_name,
Fields={
"acl": "public-read",
"key": file_name,
},
Conditions=[
{"acl": "public-read"},
{"key": file_name},
["content-length-range", file_size_min, file_size_max]
],
ExpiresIn=3600
)
# Use the signed policy to upload the file
with open(file_name, 'rb') as f:
print()
resp = requests.post(signedPolicy['url'], data=signedPolicy['fields'], files={'file': f})
print(resp)
print(resp.content)
I managed to test with Postman an exact file size and everything is working correctly. The condition that I used is:
const Conditions = [
["content-length-range", 30789588, 30789588],
["eq", "$Content-Type", "image/jpeg"]
];
I downloaded the 30MB file from here: https://sample-videos.com/download-sample-jpg-image.php
When I change the size of the content length to 30789587 I get the following:
<Error>
<Code>EntityTooLarge</Code>
<Message>Your proposed upload exceeds the maximum allowed size</Message>
<ProposedSize>30789588</ProposedSize>
<MaxSizeAllowed>30789587</MaxSizeAllowed>
</Error>
And with a content length of 30789589:
<Error>
<Code>EntityTooSmall</Code>
<Message>Your proposed upload is smaller than the minimum allowed size</Message>
<ProposedSize>30789588</ProposedSize>
<MinSizeAllowed>30789589</MinSizeAllowed>
</Error>
Test with the same file I used and let's see if it works for you.
Edit
Executing the Python code to DigitalOcean Spaces gave the same error: EntityTooSmall without any other information.
Executing the same code to AWS S3 is working correctly. Also, the error message, when I change the range, is more useful.
It seems something with the range is not implemented correctly in DigitalOcean Spaces