■RANGEリクエストについて
ファイルレジュームに使われるコンテンツの一部をリクエストするhttp-header
iPhoneで動画・音楽再生時にRANGEリクエストに対応しているか確かめるため、下記の工程を踏む
1.RANGEリクエストで対象ファイルを1バイト取得
2.httpステータス206(RANGEで取得成功)が返ってくると対応していると見なし再生を開始する。
■RANGEリクエストに関するnginxの仕様
nginxをリバースプロキシとして、キャッシュサーバの役割をさせているとき、
下記のような仕様であるため、上記のiPhoneからのリクエスト時に不具合がある。
1.(キャッシュを保持しない時)RANGEリクエストにも関わらず、プロキシ先から対象ファイル全体を取得し、ファイル全体を返答。httpステータスは200で返るため、iPhoneからは再生不可であると見なされ再生されない。
2.(キャッシュを保持している時)RANGEリクエストの通り、対象ファイルの一部分を返答。
ステータスコード206で返答するため、再生可能。
■対応策①rangeリクエストをキャッシュキーに含む
nginx.confにて指定する、proxy_cache_keyに"$http_range"を含む。
・メリット
キャッシュを保持している・いないに関わらずRANGEリクエストに対して正確に返答できる。
・デメリット
指定RANGEごとに別ファイルと扱われるため、キャッシュ量が増える。
たとえ一度ファイル全体キャッシュを持っていても同RANGEリクエストされたときのキャッシュを保持していなければproxy_passの先にファイルを取りに行くことになる。
■対応策②ソース書き換え
下記の質問サイトで、パッチが紹介されている。
この通り修正し、コンパイルしなおすと、206リクエストに対応で得きる。
https://www.ruby-forum.com/topic/4151967
引用
HG changeset patch
Parent >8a7ee0318b175b8d76275c5d34707eb52b276188
Upstream: allow ranges for cacheable >replies.diff --git a/src/http/ngx_http_upstream.c >b/src/http/ngx_http_upstream.c
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -3680,10 +3680,9 @@ >ngx_http_upstream_copy_allow_ranges(ngx_if (NGX_HTTP_CACHE)
- if (r->cached) { + if (r->cached || r->upstream->>cacheable) { r->allow_ranges = 1; return NGX_OK;
- }
endif
引用終わり
・メリット
キャッシュを保持していない場合には、proxy先からファイル全体を取得し、リクエストに対しては指定RANGEのみを返答することが可能。
ファイル全体のキャッシュを持っているときには、proxy先に聞きに行くことなく、RANGEリクエストに対応できる。
・デメリット
その他の動作に何かしら影響がでる可能性あり。
(RANGEリクエストで上記の通り動作すること、単純にGETでRANGEなしのリクエストをした場合に明らかな異常が出ないことは確認済み。)