web-dev-qa-db-ja.com

HTTP範囲ヘッダー

http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35 を読んで、ファイルのダウンロードを続行する方法を見つけようとしました。

たとえば、ファイルの長さが100バイトで、100バイトすべてを持っているとします。ただし、予想されるファイルサイズがわからないため、ファイルを要求し、次のようなRangeヘッダーを指定します。

Range: bytes=100-

これは有効な範囲リクエストですか?

77
dhruvbird

これは構文的には有効なリクエストですが、満足できるリクエストではありません。そのセクションをさらに見ると、次のことがわかります。

構文的に有効なbyte-range-setに、first-byte-posがentity-bodyの現在の長さよりも短いbyte-range-specが少なくとも1つ含まれている場合、または-サフィックス長がゼロの場合、バイト範囲セットは満たされます。そうでない場合、バイト範囲セットは満足できません。 byte-range-setが満足できない場合、サーバーはステータス416(要求範囲が満足できない)の応答を返すべきである(SHOULD)。それ以外の場合、サーバーは、エンティティ本体の充足可能な範囲を含むステータス206(部分コンテンツ)の応答を返す必要があります。

したがって、あなたの例では、サーバーはそのファイルの有効なバイト範囲ではないため、416を返すはずです。

53
Marc Novakowski

Wrikken が示唆するように、これは有効なリクエストです。クライアントがメディアを要求しているとき、またはダウンロードを再開しているときも非常に一般的です。

多くの場合、クライアントは、Accept-Ranges応答を探すだけでなく、サーバーが範囲内の要求を処理するかどうかをテストします。 Chromealwaysは、ビデオの最初のGETリクエストでRange: bytes=0-を送信するため、無視できないものです。

クライアントのリクエストにRange:が含まれている場合は、たとえ不正な形式であっても、部分的なコンテンツ(206)の応答を期待しています。 HTML5ビデオの再生中に前方にシークすると、ブラウザは開始点のみを要求します。例えば:

Range: bytes=3744-

そのため、クライアントがビデオを適切に再生するには、サーバーがこれらの不完全な範囲要求を処理できる必要があります。

質問で指定した「範囲」のタイプは、次の2つの方法で処理できます。

最初に、応答で指定された要求された開始点で応答し、次にファイルの合計長から1を引いた値を要求できます(要求されたバイト範囲はゼロから始まります)。例えば:

要求:

GET /BigBuckBunny_320x180.mp4 
Range: bytes=100-

応答:

206 Partial Content
Content-Type: video/mp4
Content-Length: 64656927
Accept-Ranges: bytes
Content-Range: bytes 100-64656926/64656927

次に、リクエストで指定された開始点と無制限のファイル長(サイズ)で返信できます。これは、総長が不明なWebキャストまたはその他のメディア用です。例えば:

要求:

GET /BigBuckBunny_320x180.mp4
Range: bytes=100-

応答:

206 Partial Content
Content-Type: video/mp4
Content-Length: 64656927
Accept-Ranges: bytes
Content-Range: bytes 100-64656926/*

ヒント:

常に範囲に含まれるコンテンツの長さで応答する必要があります。開始から終了までの範囲が完全な場合、コンテンツの長さは単に差になります。

リクエスト:範囲:バイト= 500-1000

応答:コンテンツ範囲:バイト500-1000/123456

範囲はゼロインデックスであるため、Range: bytes=0-999は実際には999ではなく1000バイトを要求しているため、次のような応答を行います。

Content-Length: 1000
Content-Range: bytes 0-999/123456

または:

Content-Length: 1000
Content-Range: bytes 0-999/*

ただし、一部のメディアプレーヤーはファイルサイズから期間を把握しようとするため、可能であれば後者の方法を避けてください。リクエストがメディアコンテンツに対するものである場合(これは私の考えです)、応答にその期間を含める必要があります。これは、次の形式で行われます。

X-Content-Duration: 63.23 

これは浮動小数点である必要があります。 Content-Lengthとは異なり、この値は正確である必要はありません。これは、プレーヤーがビデオを探し回るのに役立ちます。 Webキャストをストリーミングしていて、それがどれくらいの長さであるかについての一般的な考えしか持っていない場合、それを完全に無視するのではなく、推定期間を含めることをお勧めします。したがって、2時間のWebキャストには、次のようなものを含めることができます。

X-Content-Duration: 7200.00 

Webmなどの一部のメディアタイプでは、次のようなコンテンツタイプも含める必要があります。

Content-Type: video/webm 

これらはすべて、特にHTML5でメディアを適切に再生するために必要です。期間を指定しない場合、プレーヤーはファイルサイズから期間(シークを可能にするため)を把握しようとしますが、これは正確ではありません。これは問題ありませんが、ウェブキャストやライブストリーミングには必要ですが、ビデオファイルの再生には適していません。 FFMPEGなどのソフトウェアを使用して期間を抽出し、データベースまたはファイル名に保存することもできます。

X-Content-DurationContent-Durationを支持して段階的に廃止されているため、これも含めます。 「0-」リクエストに対する基本的な応答には、少なくとも次のものが含まれます。

HTTP/1.1 206 Partial Content
Date: Sun, 08 May 2013 06:37:54 GMT
Server: Apache/2.0.52 (Red Hat)
Accept-Ranges: bytes
Content-Length: 3980
Content-Range: bytes 0-3979/3980
Content-Type: video/webm
X-Content-Duration: 2054.53
Content-Duration: 2054.53

もう1つのポイント:Chromeは、常に最初のビデオリクエストを次のように開始します。

Range: bytes=0-

一部のサーバーは、応答として通常の200応答を送信しますが、それを受け入れます(ただし、再生オプションは制限されます)が、サーバーが範囲を処理するよりも、表示する代わりに206を送信します。 RFC 2616 は、範囲ヘッダーを無視してもかまいません。

135
Victor Stoddard

マーク・ノバコフスキーの答えとは反対に、それは何らかの理由で多くの人によって支持されてきました、はい、それは有効で満足できる要求です。

実際、Wrikkenが指摘したように、標準はまさにそのような例です。実際には、Firefoxはそのようなリクエストに(206コードで)期待通りに応答します。これはプログレッシブダウンロードの実装に使用するものです。つまり、ポーリングでリアルタイムに成長する長いログファイルの末尾のみを取得します。

7
user3198011

2019年に上記のビクターストッダードの答えに出くわし、希望に満ちて目を見張る人たちのために、次のことに注意してください:

a)Firefox 41でX-Content-Durationのサポートが削除されました: https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Releases/41#HTTP

b)Firefoxでは.oggオーディオと.ogvビデオでのみサポートされ、他のタイプではサポートされていないと思います。

c)Chromeでこれまでまったくサポートされていなかったことがわかりませんが、それは単に私の側の研究の不足かもしれません。しかし、その存在の有無は、Chrome 71。

d)「Content-Duration」が「X-Content-Duration」に置き換わる場所はどこにも見つかりません。「X-Content-Duration」は後続のヘッダー名が存在するほど長くは生きていないと思います。

これは、今日の時点で、ChromeまたはFFに継続時間を知らないストリーム(たとえばffpegパイプの出力)を含むwebmまたはogvコンテナを提供したい場合、 Firefox 64.0は、レンジリクエストを介してサービスを提供するかどうかに関係なく、これらのスクラブを可能にするために中途半端な試みを行いますが、混乱してスローされます適切と思われるよりも数倍多くシークした場合、ストリームが完全にダウンロードされるまでホイールを回転させます。Chromeは試してさえいません。ストリーム全体が終了するまでplaying

3
Chris McDonough