Railsはまりポイント:productionモードでのsend_file()による画像表示

2012/01/31

当サイトはRuby on Railsで開発してますが、初めてRails 3.0.10 + Apache + Passenger + productionモードで動かしたので、その時のはまりポイントをちょこちょこ書いていこうと思います。

今回ですが、send_file()でのインライン画像表示についてです。

事情があってpublicフォルダに直接画像を置きたくない場合(認証をかけたい場合など)、下記のように行っています。

    
  def show_image(id)
    file_path = get_image_path(id)
    send_file(file_path, :disposition => 'inline')
  end
  

これだと、developmentモードでは動くのですが、実際に運用している環境(Apache + Passenger + productionモード)では、読み込んだファイルがクライアント側に渡ってくれません。(content-lengthを確認すると0になっています)

調べてみた結果、config/environments/production.rbの下記を有効にする必要がありました。(デフォルトではコメントアウトされています)

config/environments/production.rb
    
config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect'
  

上記を有効にすることで、Rails側からsend_file()を行った際に X-Accel-Redirect ヘッダーにてPassengerに画像ファイルのパスが渡り、Passengerにてクライアント側に送信する動作を行ってくれるようです。

ただ、今このエントリを書くために再度調べてると、Apacheの場合は下記を有効にすると書いてあるサイトをちらほら見かけますね。。しかし、実際に試してみると 、下記を有効にしても動作しないようですので、Passengerの動作が変わったのかもしれません。

    
# Specifies the header that your server uses for sending files
# config.action_dispatch.x_sendfile_header = "X-Sendfile"
  

コメント(2 件)

yoshinoya ussie  -  2013/12/07 09:26:46  
Wさま>
コメントありがとうございます。
production.rbのコメントにも'X-Accel-Redirect'は「for nginx」と書かれてますので私もその認識だったんですが、実際に動作を見てみるとウチの環境では'X-Sendfile'では動かなかったのではまった次第です。。
他の環境で動かしたことがないので想像ですが、間にPassengerが介在する環境だとX-Accel-Redirectを解釈するのはPassengerだと思うので、以前はfor Apacheとfor nginxで見るヘッダを変えてたけど、ある時点でnginxにあわせて'X-Accel-Redirect'を見るように変えたのではないかと・・。
おそらくmod_proxyとかを使っててWebrickとかをバックエンドにしてる環境だと普通に'X-Sendfile'で動作するんではないかと思います。
W  -  2013/12/06 17:59:16  
'X-Accel-Redirect' は nginx の設定ではないでしょうか? apache の設定は 'X-Sendfile' で正しいように思えます。(Apache/2.2.15, Rails 3.2.13 時点)

コメントの投稿

※必須入力です。
※入力いただいた場合、コメント欄からリンクされます。

※必須入力です。HTMLタグは使用できません。