RailsでSSLのページ内でのcloudfront表示(gem paperclipを使用している際の回避方法)

Secure paperclip urls only for secure pages

http://stackoverflow.com/questions/3770728/secure-paperclip-urls-only-for-secure-pages

まさに上記の状態だったのだけども。
ハマったので記事にしておきます。

環境

Rails 3.2.2

ハマったポイント

Rails 3.2.2にActionController::Responseというオブジェクトは無い

正解はActionDispatch::Response。

return は [status, headers, response] を想定

gems/rack-1.4.1/lib/rack/etag.rbを見ればわかるが、responseにStringは想定していないので、stackoverflowのbody(つまりString)だと、eachメソッドが無いのでエラー。

実装

class PaperclipS3UrlRewriter
  def initialize(app)
    @app = app
  end

  def call(env)
    status, headers, response = @app.call(env)
    if response.is_a?(ActionDispatch::Response) && response.request.protocol == 'https://' && headers["Content-Type"].include?("text/html")
      response.body = response.body.gsub("http://#{ENV['CLOUDFRONT_URL']}", "https://#{ENV['CLOUDFRONT_URL']}")
      headers["Content-Length"] = response.body.length.to_s
      [status, headers, response]
    else
      [status, headers, response]
    end
  end
end

追記

http://api.rubyonrails.org/classes/Object.html

ここを見ると
AbstractResponse = ActionController::Response = ActionDispatch::Response
となっていて、いまいち関係性がわからんなと。


[PR]Spreeの情報を集めています。

ECを持ちたい方、仕事でECを使いたい方向けのコミュニティサイトです。
このサイトでは世界で最も使用されているECの1つであるSpreeについての情報を提供しています。
http://spreecommerce.jp/