开发者

Paperclip: PDF thumbnail has wrong content_type on S3

I'm using Paperclip 2.3.5 within a Rails app to store PDF documents on Amazon S3. For every PDF a JPG thumbnail is generated by ImageMagick. Im' using this configuration in the model:

has_attached_file :file,
                  :styles => { :thumb => { :geometry => "200x200>",
                                           :format => :jpg
                                         } },
                  :whiny => false,
                  :storage => :s3,
                  :s3_credentials => "#{RAILS_ROOT}/config/s3.yml",
                  :s3_permissions => 'authenticated-read',
                  :s3_headers => { 'Expires' => 1.year.from_now.httpdate },
                  :url => "s3.amazonaws.com",
                  :path => "documents/:id/:style/:basename.:extension",
                  :bucket => 'mybucket'

But there is problem: The generated thumbnail is uploaded to S3 with the content_type "application/pdf", which is WRONG, because it's a JPG (you can see the content_type of a file on S3 with a S3 exploring tool like Cyberduck). For the original PDF file this content_type is correct, but not for the thumbnail. This causes trouble in some browsers (e.g. Chrome or Safari) which don't show the thumbnail inline.

Beware: The content_type stored in my database (field "file_content_type") is "application/pdf", which is still correct, because it's the content_type for the original file.

How can I override th开发者_StackOverflow社区e content_type for a thumbnail if it should be different from the original file?


This is how we fixed it on brighterplanet.com/research, which has pdf documents and png previews:

has_attached :pdf_document,
  :storage => :s3,
  # [... other settings ...]
  # PDFs work better in Windows 7 / IE if you give them content-type: attachment
  :s3_headers => { 'Content-Disposition' => 'attachment' },
  :styles => { :preview => { :geometry => '135',  :format => :png } }

after_save :fix_thumbnail
def fix_thumbnail(force = false)
  # application/pdf and application/x-pdf have both been seen...
  return unless force or pdf_document_content_type.include?('pdf')

  # set content type and disposition
  s3 = AWS::S3.new(YAML.load(File.read("#{RAILS_ROOT}/config/aws_s3.yml")))
  t = s3.buckets[PAPERCLIP_BUCKET].objects[pdf_document.path(:thumbnail)]
  content = t.read
  t.write(:data => content, :content_type => 'image/png', :content_disposition => 'inline', :acl => :public_read)

  nil
end


I had to overcome this, not the most elegant solution but I forked Paperclip and hold the patch in my own git repo - https://github.com/svetzal/paperclip

It is a direct replacement for Paperclip, just put in your environment.rb

gem 'twm_paperclip', :lib => 'paperclip'


This is fixed in paperclip >= 2.7, as you can see here:

https://github.com/thoughtbot/paperclip/blob/v2.7/lib/paperclip/storage/s3.rb#L290

the mime-type of the file that is written to S3 is determined specifically before uploading.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜