To start, I'm using ruby's aws-sdk, but what I'm facing seems to be a misunderstanding of S3's presigned posts.
What I want to be able to do is ensure that anything uploaded to S3 with my presigned post is a video.
What I've tried doing is setting content_type_starts_with: "video/"
in the presigned_post hash. This causes all uploads to be rejected with Policy Condition failed: ["starts-with", "$Content-Type", "video/"]
.
I then tried just content_type: "video/mp4"
, but this causes s3 to allow any file to be uploaded, and then just tags it with Content-Type: "video/mp4"
in the metadata.
I then noticed that when I upload a file without a Content-Type constraint, S3 will tag the file as binary/octet-stream
. So I tried the first method again, but this time with content_type_starts_with: "binary/"
. Same results as before, Policy Condition Failed
.
How am I supposed to use the Content-Type field? It does't seem to ever do what I want it to do.
Here's a snippet of the code I'm using:
# In the controller
client = Aws::S3::Client.new(region: 'us-east-1')
resource = Aws::S3::Resource.new(client: client)
bucket = resource.bucket("my-bucket")
object_id = SecureRandom.uuid
object = bucket.object(object_id)
@presigned_post = object.presigned_post({
acl: "private",
content_length_range: 0..104857600, # 100 MB
content_type_starts_with: "video/",
})
# In the presigned post erb
<form action="<%= presigned_post.url %>" method="post" enctype="multipart/form-data">
<% presigned_post.fields.each do |name, value| %>
<input type="hidden" name="<%= name %>" value="<%= value %>"/>
<% end %>
<input type="file" name="file" accept="*.mp4,*.ogg,video/*" />
<input type="submit">
</form>
I just had a very similar problem and I think I solved it. I hope this helps.
I realised that setting the content_type_starts_with
does not actually restrict what type of file is uploaded, but it restricts what the content-type
key in your form data actually is, but you'll still need to set the content type that the form is going to post.
Since I'm doing a client-side upload with JavaScript, I just added this to my upload code:
formData.set('content-type', file.type)
where formData
is an instance of a FormData
object that I eventually send to the server through an XMLHttpRequest.
After doing this, uploading a pdf will start the upload but not save the file on S3 because the MIME type restriction.
Let me know if you need some more information, I based some of my upload code of this: http://blog.teamtreehouse.com/uploading-files-ajax
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With