Skip to content
Browse files

Made Content-Type a configuration-level option to better fix issue #63.

I still needed the Content-Type option, but I understand that if you include Content-Type in your
policy document, but don't include the corresponding field in your form, S3 will return 403's.

A better solution is to make it a configuration level option. I also added documentation
to clearly specify that you will have to add a Content-Type field to your form.
  • Loading branch information...
1 parent c5b5330 commit 7247cc4acaef761457a580ed9020275bef6c278d @colinyoung colinyoung committed Feb 17, 2013
Showing with 42 additions and 3 deletions.
  1. +34 −0 README.md
  2. +4 −3 lib/carrierwave_direct/uploader.rb
  3. +4 −0 spec/uploader_spec.rb
View
34 README.md
@@ -163,6 +163,37 @@ Note if you're using Rails 3.0.x you'll also need to disable forgery protection
Once you've uploaded your file directly to the cloud you'll probably need a way to reference it with an ORM and process it.
+## Content-Type / Mime
+
+The default amazon content-type is "binary/octet-stream" and for many cases this will work just fine. But if you are trying to stream video or audio you will need to set the mime type manually as Amazon will not calculate it for you. All mime types are supported: [http://en.wikipedia.org/wiki/Internet_media_type](http://en.wikipedia.org/wiki/Internet_media_type).
+
+First, tell CarrierWaveDirect that you will include your content type manually by adding to your initializer:
+
+ CarrierWave.configure do |config|
+ # ... fog configuration and other options ...
+ config.will_include_content_type = true
+ end
+
+Then, just add a content-type element to the form.
+
+ <%= direct_upload_form_for @uploader do |f| %>
+ <%= text_field_tag 'Content-Type', 'video/mpeg' %><br>
+ <%= f.file_field :avatar %>
+ <%= f.submit %>
+ <% end %>
+
+You could use a select as well.
+
+ <%= direct_upload_form_for @uploader do |f| %>
+ <%= select_tag 'Content-Type', options_for_select([
+ ['Video','video/mpeg'],
+ ['Audio','audio/mpeg'],
+ ['Image','image/jpeg']
+ ], 'video/mpeg') %><br>
+ <%= f.file_field :avatar %>
+ <%= f.submit %>
+ <% end %>
+
## Processing and referencing files in a background process
Processing and saving file uploads are typically long running tasks and should be done in a background process. CarrierWaveDirect gives you a few methods to help you do this with your favorite background processor such as [DelayedJob](https://github.com/collectiveidea/delayed_job) or [Resque](https://github.com/defunkt/resque).
@@ -294,6 +325,9 @@ As well as the built in validations CarrierWaveDirect provides, some validations
config.min_file_size = 5.kilobytes # defaults to 1.byte
config.max_file_size = 10.megabytes # defaults to 5.megabytes
config.upload_expiration = 1.hour # defaults to 10.hours
+ config.will_include_content_type = true # defaults to false; if true, content-type will be set
+ # on s3, but you must include an input field named
+ # Content-Type on every direct upload form
end
## Testing with CarrierWaveDirect
View
7 lib/carrierwave_direct/uploader.rb
@@ -61,13 +61,14 @@ def policy(options = {})
options[:expiration] ||= self.class.upload_expiration
options[:min_file_size] ||= self.class.min_file_size
options[:max_file_size] ||= self.class.max_file_size
+
+ conditions = [ ["starts-with", "$utf8", ""], ["starts-with", "$key", store_dir] ]
+ conditions << ["starts-with", "$Content-Type", ""] if self.class.will_include_content_type
Base64.encode64(
{
'expiration' => Time.now.utc + options[:expiration],
- 'conditions' => [
- ["starts-with", "$utf8", ""],
- ["starts-with", "$key", store_dir],
+ 'conditions' => conditions + [
{"bucket" => fog_directory},
{"acl" => acl},
{"success_action_redirect" => success_action_redirect},
View
4 spec/uploader_spec.rb
@@ -434,6 +434,10 @@ def have_condition(field, value = nil)
subject.success_action_redirect = "http://example.com/some_url"
conditions.should have_condition("success_action_redirect" => "http://example.com/some_url")
end
+
+ it "'content-type' only if enabled" do
+ conditions.should have_condition('Content-Type') if subject.class.will_include_content_type
+ end
context "'content-length-range of'" do
def have_content_length_range(options = {})

0 comments on commit 7247cc4

Please sign in to comment.
Something went wrong with that request. Please try again.