挑戦する
したがって、初期データは次のとおりです。
- Ruby on Railsを使用している場合、ユーザーリクエストはNginxを経由します。
- 大きなファイルを提供する必要があります。
- ファイルを直接ダウンロードできないようにする必要があります。ファイルをアップロードする決定はRailsアプリケーションによって行われます。
解決策
英語圏の情報源への言及を避けたくはありませんが、公式のドキュメントを通過することはできません。 Nginxには、 X-Accel-Redirectのすばらしい部分があり、それによってタスクが解決されます。 次に、それを機能させる方法を示します。
Railsアプリケーションのconfig / environment / production.rbファイルで、次の行のコメントを解除する必要があります。
config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx
nginxの設定では、次を追加する必要があります。
proxy_set_header X-Accel-Mapping /mnt/filestorage/=/private_files/; location /private_files/ { internal; alias /mnt/filestorage/; }
それだけです セットアップが完了しました。 ファイルのダウンロードの例で、これらすべてがどのように機能するかを見てみましょう。 この段階では、NginxとRailsアプリケーションはすでに構成され、動作していると考えています。
1.ブラウザがファイルを要求します
# HTTP GET /download/kino.avi HTTP/1.1
2. Nginxはこのリクエストを受信し、レールをアプリケーションに渡し、別のヘッダーを追加します。
# Nginx proxy_set_header X-Accel-Mapping /mnt/filestorage/=/private_files/;
# HTTP GET /download/kino.avi HTTP/1.1 X-Accel-Mapping: /mnt/filestorage/=/private_files/
3.アプリケーションのRailsコントローラーは、このユーザーにファイルを提供できるかどうかを確認し、send_fileを呼び出します。 この時点で、絶対パスを使用することが重要です。
# rails ( app/controllers/downloads_controller.rb) send_file('/mnt/filestorage/kino.avi')
4. Rails(またはRack)がこのファイルの処理方法を決定します。 この段階の前半では、ファイルの内容が応答本文に含まれていました。 しかし、Railsアプリケーションの設定を変更すると、ファイルのコンテンツの代わりに、応答にX-Accel-Redirectヘッダーが含まれ、Nginxが処理します。 応答本文は空になります。 また、ファイルパスは、X-Accel-Mappingヘッダーからの情報に従って変更されます。
# Rails (config/environments/production.rb) config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect'
# HTTP HTTP/1.1 200 OK X-Accel-Redirect: /private_files/kino.avi Content-Type: application/octet-stream Content-length: ... Content-Disposition: attachment; filename="kino.avi"
5. Nginxはこのヘッダーを処理し、適切な場所を見つけ、ファイルパスを変更してユーザーに提供します。
# Nginx location /private_files/ { internal; alias /mnt/filestorage/; }
# HTTP HTTP/1.1 200 OK Content-Type: application/octet-stream Content-Length: ... Content-Disposition: attachment; filename="kino.avi" < /mnt/filestorage/kino.avi>
6.ユーザーのブラウザがファイルを受信します。
Passengerを使用する場合、Nginx構成では、
proxy_set_header
代わりに
proxy_set_header
を使用する必要があります