4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Rails:PaperclipにURLで画像を入れたらcontent_typeが違うと怒られた

Last updated at Posted at 2016-06-27

経緯

PaperclipにURLで画像を登録したら、一部の画像がContent typeのvalidationで弾かれた。

Railsは4.2.6、Paperclipは4.3.6でした。

エラーメッセージ

[paperclip] Content Type Spoof: Filename 1467013624.jpg 
(application/octet-stream from Headers, ["image/jpeg"] from Extension), 
content type discovered from file command: image/jpeg. 
See documentation to allow this combination.

レスポンスヘッダはapplication/octet-streamだけど拡張子から推測するにimage/jpegだよね?変でしょ?直して!ってことらしい。

issueになってた

Content Type Spoofのエラーを出さない方法は、
config/initializer/paperclip.rbに

require 'paperclip/media_type_spoof_detector'
module Paperclip
  class MediaTypeSpoofDetector
    def spoofed?
      false
    end
  end
end

こう書くらしい。
確かにエラーは出なくなった。
でもまだvalidationで弾かれる。

原因

こんなふうに書いてた

data = Paperclip.io_adapters.for(url)
data.original_filename = url
Image.new(image: data)

ここで

puts data.content_type

すると、

application/octet-stream

って返ってくる。
image/*じゃないからダメだったらしい。

じゃあこのエラーメッセージはどうやってimage/*のcontent typeをゲットしてるんだろうとエラー元を見てみた。
そしたらファイル名からcontent typeを教えてくれるのを見つけた。
https://github.com/thoughtbot/paperclip/blob/e60f00027704298455c039e111d96bcf46e12822/lib/paperclip/media_type_spoof_detector.rb#L57

というわけで

data = Paperclip.io_adapters.for(url)
data.original_filename = url
data.content_type = MIME::Types.type_for(url).first.content_type
return Image.new(image: data)

こうなった。
MIME::Types.type_for(url)はArrayで返ってくるみたいだから最初を取り出した。

めでたし。

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?