`x_sendfile_header` が未設定の場合に `Rack::Sendfile` をスタックから除外
config.action_dispatch.x_sendfile_header が nil のとき、Rack::Sendfile ミドルウェアをスタックに追加しないよう変更されました。このミドルウェアはヘッダーが未設定の場合にnoopとして動作するため、スタックへの追加自体が不要でした。
背景
Rack::Sendfile は、WebサーバーがX-Sendfileヘッダーを解釈して静的ファイルを直接配信する機能を有効化するミドルウェアです。config.action_dispatch.x_sendfile_header に "X-Sendfile" や "X-Accel-Redirect" などのヘッダー名を設定することで機能します。
この設定が nil(デフォルト)の場合、Rack::Sendfile はリクエストを素通りさせるだけで何も行いません。にもかかわらず、従来の実装ではヘッダーの設定状態に関わらず常にミドルウェアスタックへ追加されていました。
nil を渡しても機能しないミドルウェアをスタックに積み続けることは、毎リクエストごとに無意味な処理を追加することになります。本PRはこの無駄を取り除くための変更です。
技術的な変更
railties/lib/rails/application/default_middleware_stack.rb における build_stack メソッドの変更は、条件分岐を1つ追加するだけのシンプルなものです。
変更前:
middleware.use ::Rack::Sendfile, config.action_dispatch.x_sendfile_header
変更後:
if config.action_dispatch.x_sendfile_header
middleware.use ::Rack::Sendfile, config.action_dispatch.x_sendfile_header
end
x_sendfile_header のtruthy性を確認し、値が存在する場合のみ Rack::Sendfile をスタックへ追加します。nil および空文字列の場合はスキップされます。
テスト側(railties/test/commands/middleware_test.rb)では、デフォルト設定のアプリケーションにおけるミドルウェア一覧の期待値から "Rack::Sendfile" が削除されました。また、Rack::Sendfile を基準点として使用していたテスト(insert middleware after など)は Rack::Runtime を基準点とするよう更新されています。
設計判断
条件が満たされない場合はミドルウェア自体をスタックに載せないというアプローチが採用されました。
代替案として、ミドルウェア内部でnoopとして処理する現行の動作を維持することも考えられます。しかしミドルウェアスタックは各エントリがリクエストごとに呼び出されるため、機能しない処理をスタックに含め続けることはアプリケーションのデフォルト構成を不必要に複雑にします。rails middleware コマンドの出力からも不要なエントリが消えるため、ミドルウェア構成の可読性も向上します。
x_sendfile_header の設定は明示的なオプトインを必要とする機能であり、未設定(nil)が圧倒的多数の構成です。デフォルトパスを最適化するこの判断は、「不要なものはデフォルトで含まない」というRailsの設計方針と一致しています。
まとめ
本PRは、機能しないミドルウェアをデフォルトスタックから除外することで、Railsアプリケーションのデフォルト構成をより正確に反映させた変更です。変更の影響を受けるのはデフォルト設定のアプリケーションのみで、x_sendfile_header を明示的に設定している場合の動作は従来と変わりません。