HTTP範囲ヘッダー


81

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

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

Range: bytes=100-

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


5
えーと、その下の例では、「bytes = 9500-」が有効であると引用されているので、....
Wrikken 2010

1
最新の参照はRFC7233-httpwg.github.io/specs/rfc7233.html
Mark Nottingham

2
最初にHEADリクエストを行い、ファイルの長さを確認できます。
Matheus Rocha

回答:


55

これは構文的に有効な要求ですが、充足可能な要求ではありません。そのセクションをさらに見ると、次のことがわかります。

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

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


では、クライアントがHEAD呼び出しを行わずにダウンロードを再開して、最初にコンテンツの長さを計算し、次に計算を行って実際のコンテンツをフェッチする方法はありますか?私は、「そのようなバイトの後にすべてのバイトをください...」のようなある種のオープンアドレス法を意味します
dhruvbird 2010

5
クライアントは、元のリクエストからのすべてのデータを持っているかどうかをすでに知っています-元の応答でContent-Lengthヘッダーを受信して​​いるか、チャンク化されている場合は、長さゼロのチャンクを受信して​​、応答は完了しました。この状態を保存しておらず、ディスク上にバイトのチャンクがある場合は、はい、HEADリクエストを実行するか、Rangeヘッダーを使用してバイト範囲を要求する必要があります。416が返される場合は、すべてのバイトがあることがわかっている応答。
Marc Novakowski 2010

Expect-Continueを使用すると、チャンクのストリーミングを多かれ少なかれ希望どおりに実行できると思いますか?
MJB 2011年

@MarcNovakowski実際には、wgetの場合を考えて-cフラグを使用します。wgetは完了したファイルに関するメタデータを保持しないため、ディスク上のファイルのサイズが99バイトであると想定します。wgetはバイト範囲「100-」を要求しますが、要求はファイルの終わりを1過ぎただけなので、サーバーは長さ0の応答で応答する必要があると思います。
dhruvbird 2014年

148

以下のようWrikkenが提案され、それは有効な要求です。また、クライアントがメディアを要求したり、ダウンロードを再開したりする場合もよくあります。

クライアントは、サーバーがAccept-Ranges応答を探すだけでなく、遠隔要求を処理するかどうかをテストすることがよくあります。Chromeは常にRange: bytes=0-動画の最初のGETリクエストを送信するため、これを却下することはできません。

クライアントが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/*

チップ:

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

リクエスト:範囲:bytes = 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でメディアが正しく再生されるために必要です。期間を指定しない場合、プレーヤーはファイルサイズから(シークを可能にするために)期間を計算しようとする場合がありますが、これは正確ではありません。これは問題なく、Webキャストやライブストリーミングには必要ですが、ビデオファイルの再生には理想的ではありません。FFMPEGなどのソフトウェアを使用して期間を抽出し、データベースまたはファイル名に保存することができます。

X-Content-Durationを優先して段階的に廃止されているContent-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は、範囲ヘッダーを無視することは許容できると述べています。


コンテンツが固定期間のないライブビデオストリームである場合はどうしますか?
Joel Barsotti 2014

@ジョエル、あなたはそれを知らなくても、期間で返信する必要があります。その場合は、0.0を試してください。クライアントの場合、通常はライブストリームをスキャンできないため、期間は関係ありません。0.0が機能しない場合は、1000000.00のような非常に高いものを試してください。
ビクターストッダード2014

@VictorStoddardは、クライアント要求にRangeヘッダーが存在しない場合に、チャンクストリーミングを通常のファイルダウンロードに適用できますか?その場合、サーバーはどのように応答する必要がありますか?
gkiko 2015

@gkikoチャンク転送エンコーディングでContent-Lengthの代わりにTransfer-Encodingヘッダーを使用する以外に大きな違いはありません。チャンクは単一のファイルから取得でき、サーバーはチャンクサイズを設定できます。クライアントは、チャンクを受信したときに、それらをバッファリングしてつなぎ合わせる必要があります。または、HTTPストリーミングは、メディアファイルの事前に記録されたセグメントを使用し、それらは個別の部分(tsファイル)としてサーバーに保存されます。これらのセグメントは、インデックスファイルから取得した通常のHTTPファイルGETリクエストを使用して提供されます。セグメント化は難しいと思いましたが、それは何年も前のことです。
ビクターストッダード2015

Content-Length:64656927 Accept-Ranges:バイトContent-Range:バイト100-64656926Content-Lengthが「64656827」ではないのはなぜですか。
iwind 2018

7

何らかの理由で多くの人から支持されてきたMarkNovakowskiの回答とは異なり、はい、それは有効で充足可能な要求です。

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


2
マーク・ノヴァコウキの答えをもう一度読んでください。「充足可能」は、彼が引用したRFCで特定の意味を持っています。要求されたバイトがファイルの長さを超えているため、この要求は満たされません。
スコットラム

1
Firefoxは要求に応答するが、それはhttpサーバであることをソフトウェア要素ではありません
コリン・D

はい、申し訳ありませんが、私は、Apacheを意味
フランチェスコPotortì

5

2019年に上記のVictorStoddardの答えに出くわし、希望に満ちて目を凝らしている人々のために、次のことに注意してください。

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

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

c)Chromeでこれまでサポートされていたことがまったくわかりませんが、それは私の側の調査が不足しているだけかもしれません。しかし、その存在または不在は、Chrome 71の今日の時点で、webmまたはogvビデオに何らかの影響を与えていないようです。

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

これは、今日の時点で、期間がわからないストリーム(ffpegパイプの出力など)を含むwebmまたはogvコンテナーを、ChromeまたはFFに提供し、それらをスクラブ可能にすることを意味すると思います。 HTML 5ビデオ要素、あなたはおそらく運が悪いです。Firefox 64.0は、範囲要求を介してサービスを提供するかどうかに関係なく、これらをスクラブ可能にするために中途半端な試みをしますが、適切と思われる数倍を求めると、ストリームが完全にダウンロードされるまで混乱し、スピニングホイールをスローします。Chromeは試行すらしません。ただうなずいて、ストリーム全体の再生が終了するまでスクラブすることはできません。


これらの種類のファイルのサポートについて話しているFF開発者からの長いスレッドがあります。 bugzilla.mozilla.org/show_bug.cgi?id=657791
ChrisMcDonough19年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.