Paperclip- validate pdfs with content_type='application/octet-stream'
Asked Answered
M

3

9

I was using paperclip for file upload. with validations as below:

validates_attachment_content_type :upload, :content_type=>['application/pdf'], :if => Proc.new { |module_file| !module_file.upload_file_name.blank? }, :message => "must be in '.pdf' format"

But, my client complained today that he is not able to upload pdf. After investigating I come to know from request headers is that the file being submitted had content_type=application/octet-stream.

Allowing application/octet-stream will allow many type of files for upload.

Please suggest a solution to deal with this.

Musty answered 2/8, 2011 at 12:29 Comment(0)
B
8

Seems like paperclip doesn't detect content type correctly. Here is how I was able to fix it using custom content-type detection and validation (code in model):

VALID_CONTENT_TYPES = ["application/zip", "application/x-zip", "application/x-zip-compressed", "application/pdf", "application/x-pdf"]

before_validation(:on => :create) do |file|
  if file.media_content_type == 'application/octet-stream'
    mime_type = MIME::Types.type_for(file.media_file_name)    
    file.media_content_type = mime_type.first.content_type if mime_type.first
  end
end

validate :attachment_content_type

def attachment_content_type
  errors.add(:media, "type is not allowed") unless VALID_CONTENT_TYPES.include?(self.media_content_type)
end
Baynebridge answered 9/8, 2011 at 17:22 Comment(0)
B
5

Based on the above, here's what I ended up with which is compatible with PaperClip 4.2 and Rails 4:

before_post_process on: :create do    
  if media_content_type == 'application/octet-stream'
    mime_type = MIME::Types.type_for(media_file_name) 
    self.media_content_type = mime_type.first.to_s if mime_type.first  
  end
end
Britten answered 25/2, 2015 at 20:13 Comment(0)
C
3

For paperclip 3.3 and Rails 3, I did this a bit differently

before_validation on: :create do   
  if media_content_type == 'application/octet-stream'
    mime_type = MIME::Types.type_for(media_file_name) 
    self.media_content_type = mime_type.first if mime_type.first  
  end
end

validates_attachment :media, content_type: { content_type: VALID_CONTENT_TYPES } 

By the way, i needed to do this because testing with Capybara and phantom js using attach_file did not generate the correct mime type for some files.

Cubical answered 16/12, 2012 at 8:32 Comment(1)
I found that to avoid the processing of a file with the incorrect MIME type I had to use this as a before_file_post_process method.Clam

© 2022 - 2024 — McMap. All rights reserved.