rails nginx x-sendfile

rails4.2.0

http://wiki.nginx.org/NginxXSendfile

x-sendfileは、Railsのみで静的ファイルのアクセスコントロールとかをしたい時に使うといいみたい。
今回は、unicornワーカーが 少ない環境なのでワーカー確保のために使った。

コード

controller

send_fileメソッドでヘッダーに追加してくれるみたいなので、このままでOK。

# filepathは絶対パスになってる
def show
  send_file(filepath, filename: file_name)
end
config/environments/production.rb

以下をアンコメントするだけでOK。

config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx
nginx.conf
     location ~ ^/system/(.*) {
       internal;
     }

    location / {
      proxy_set_header X-Sendfile-Type X-Accel-Redirect; # いらないかも
      proxy_set_header  X-Accel-Mapping   /var/www/rails_app_name/current/public/=/;
      proxy_pass http://momiji;
  }

X-Accel-Redirectヘッダーに入ってくる値はファイルパスになっていてsend_fileと同じパスが入ってる。nginxのドキュメントルートと違うので修正が必要。
その修正というは、X-Accel-Mappingヘッダーでやっている。

ダメな例

controller
def show
  response.headers['X-Accel-Redirect'] = "/system/hoge.jpg" # nginxドキュメントルートからのパス
  send_file(filepath, filename: file_name)                                   # filepathはファイルシステムのルートからのパス
end
nginx
     location ~ ^/system/(.*) {
       internal;
     }

    location / {
      proxy_set_header X-Sendfile-Type X-Accel-Redirect; # いらないかも
      proxy_pass http://momiji;
  }

手動でヘッダーを追加しているパターン。
これだとX-Accel-Mapping が必要なくなるし一応動くのだけど、ログに`"X-Accel-Mapping header missing"`と出力されてしまうのでダメッポイ。
https://github.com/rack/rack/blob/b698f84e633426c208623282988bab0d2ac45931/lib/rack/sendfile.rb#L124


以上。