ライブコンテンツにおけるHTTP Rangeリクエストを改善する提案仕様 (RFC8673)

追記2019/11/28
RFC8673になりました


ライブコンテンツやログデータといった常に大きくなり続けるコンテンツに対するRangeリクエストを改善する提案仕様がIETFのHTTPbisで出ています。

その仕様は「HTTP Random Access and Live Content」であり、すでにWGアイテムとなっておりWorking Group Last Callを迎えようとしてます。

現状のライブコンテンツとRangeリクエス

常にコンテンツが大きくなり続けるファイルに対して、Rangeリクエストでデータを受信し続ける場合を考えます。クライアントはRangeリクエストを繰り返すような流れになります。

クライアントはRangeヘッダで1000バイト目より後ろを要求します。Rangeヘッダでは後ろの明示しないことも出来ます

HEAD /resource HTTP/1.1
Range: bytes=1000-
...


サーバはライブコンテンツのうち現在利用可能な範囲を返しますが、Content-Rangeヘッダでレスポンスデータの範囲を示します。 /* をつけることでこのコンテンツの完全な長さが不明であることを示しますが。今回のレスポンスは1000-2000バイトのコンテンツになります。

HTTP/1.1 206 Partial Content
Content-Range: bytes 1000-2000/*
...


クライアントは増えた分のコンテンツを読み込むためにまたRangeリクエストを送信します。

HEAD /resource HTTP/1.1
Range: bytes=2000-
...

提案仕様

上記の例では、Rangeリクエストを繰り返し最新分のデータを取得します。これは、毎回HTTPリクエストを行うのでオーバーヘッドがあるとともに、最新データの取得が送れる事になります。

そこで、Rangeリクエストでもライブコンテンツを受信し続けられるようにするのが今回の「HTTP Random Access and Live Content」という仕様です。

クライアントは"live"コンテンツにRangeリクエストを送る際、end positionに大きな値を指定します

GET /resource HTTP/1.1
Range: bytes=1230000-999999999999


この仕様に対応するサーバは、このリクエストを"live"コンテンツへのリクエストとして解釈し、Content-RangeにRangeヘッダのend positionと同じ値を指定します。

HTTP/1.1 206 Partial Content
Content-Range: bytes 1230000-999999999999/*

上記のレスポンスを受け取ったクライアントは、end positionに同じ値が設定されているのでサーバがこの仕様に対応しており、liveコンテンツのレスポンスであることがわかります。

実装

IETFで発表されたとおり、下記URLで動作確認できます (発表資料)

通常のリクエストをすると、現在可能な部分までのレスポンスしか取得できません

$ curl  http://ietf100.ecaspia.com:8000/live/nasatv.ts -v -H "Range:bytes=40403203-"   >/dev/null
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying 72.14.183.246...
* Connected to ietf100.ecaspia.com (72.14.183.246) port 8000 (#0)
> GET /live/nasatv.ts HTTP/1.1
> Host: ietf100.ecaspia.com:8000
> User-Agent: curl/7.47.0
> Accept: */*
> Range:bytes=40403203-
>
< HTTP/1.1 206 Partial Content
< Content-range: 40403203-42617155/*
< Date: Sun, 03 Dec 2017 07:09:53 GMT
< Transfer-encoding: chunked
< Content-type: video/mp2t
< Accept-ranges: bytes
< Cache-control: max-age=3600
<


今回の"live"コンテンツ用のRangeリクエストをすると、継続してデータがダウンロードされます

$ curl  http://ietf100.ecaspia.com:8000/live/nasatv.ts -v -H "Range:bytes=40403203-9999999999999"   >/dev/null
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying 72.14.183.246...
* Connected to ietf100.ecaspia.com (72.14.183.246) port 8000 (#0)
> GET /live/nasatv.ts HTTP/1.1
> Host: ietf100.ecaspia.com:8000
> User-Agent: curl/7.47.0
> Accept: */*
> Range:bytes=40403203-9999999999999
>
< HTTP/1.1 206 Partial Content
< Content-range: 40403203-9999999999999/*
< Date: Sun, 03 Dec 2017 07:12:36 GMT
< Transfer-encoding: chunked
< Content-type: video/mp2t
< Accept-ranges: bytes
< Cache-control: max-age=3600
<