[3] [DFN[[RUBYB[範囲単位]@en[range unit]]]]は、[[範囲要求]]や[[部分応答]]で[[表現]]のどの部分が含まれているかを記述するための[[単位]]です。
普通は [CODE(HTTP)@en[[[bytes]]]] が使われます。

* 仕様書

[REFS[
- [1] '''[CITE@en[RFC 7233 - Hypertext Transfer Protocol (HTTP/1.1): Range Requests]] ([TIME[2014-09-11 09:57:55 +09:00]] 版) <https://tools.ietf.org/html/rfc7233#section-2>'''
- [16] [CITE@en[RFC 7233 - Hypertext Transfer Protocol (HTTP/1.1): Range Requests]] ([TIME[2014-09-11 09:57:55 +09:00]] 版) <https://tools.ietf.org/html/rfc7233#section-3.1>
- [14] [CITE[Hypertext Transfer Protocol (HTTP) Parameters]] ([TIME[2014-06-13 18:52:05 +09:00]] 版) <http://www.iana.org/assignments/http-parameters/http-parameters.xhtml#range-units>
- [2] [CITE@en[RFC 2326 - Real Time Streaming Protocol (RTSP)]] ([TIME[2014-07-13 07:26:48 +09:00]] 版) <http://tools.ietf.org/html/rfc2326#section-12.29>
]REFS]

* 構文

[8] [[範囲単位]]は構文的には[[字句]]とされています [SRC[>>1]]。

[FIG(railroad)[
= [[字句]]
]FIG]

[9] [[HTTP]] と [[RTSP]] で定義されている[[範囲単位]]はすべて[[ASCII大文字・小文字不区別]]となっています
[SRC[>>1, >>2]]。明記されていませんが、すべての[[範囲単位]]は
[[ASCII大文字・小文字不区別]]と思われます。

* 文脈

[4] [[範囲単位]]は、次の場面で使われます。
[FIG(short list)[
- [CODE(HTTP)@en[[[Accept-Ranges:]]]]
- [CODE(HTTP)@en[[[Range:]]]]
- [CODE(HTTP)@en[[[Content-Range:]]]]
]FIG]

* 単位

[6] 次の[[範囲単位]]が存在しています。

[FIG(short list)[
- [CODE(HTTP)@en[[[bytes]]]]
- [CODE(HTTP)@en[[[rows]]]]
- [CODE(HTTP)@en[[[items]]]]
- [CODE(HTTP)@en[[[xpointer]]]]
- [CODE(HTTP)@en[[[smpte]]]]
- [CODE(HTTP)@en[[[smpte-30-drop]]]]
- [CODE(HTTP)@en[[[smpte-25]]]]
- [CODE(HTTP)@en[[[npt]]]]
- [CODE(HTTP)@en[[[clock]]]]
- [CODE(HTTP)@en[[[id]]]]
- [CODE(HTTP)@en[[[name]]]]
- [CODE(HTTP)@en[[[email]]]]
- [CODE(HTTP)@en[[[hostname]]]]
- [CODE(HTTP)@en[[[number]]]]
- [CODE(HTTP)@en[[[fingerprint]]]]
- [CODE(HTTP)@en[[[type]]]]
- [CODE(HTTP)@en[[[url]]]]
- [CODE(HTTP)@en[[[started_at]]]]
- [CODE(HTTP)@en[[[updated_at]]]]
- [CODE(HTTP)@en[[[version]]]]
- [CODE(HTTP)@en[[[none]]]]
]FIG]

[15] [[HTTP]] については [[IANA登録簿]]があります [SRC[>>14]]。 [[RFC 7233]]
で導入されました。

[5] [[HTTP]] では、 [CODE(HTTP)@en[[[bytes]]]] が規定されているほか、
新しい単位は [[IANA]] に登録する[RUBYB[べき]@en[ought to]] [SRC[>>1]] とされています。

[7] [[RTSP]] では[CODE(HTTP)@en[smpte][SMPTE時刻符号]]、
[CODE(HTTP)@en[smpte-30-drop][SMPTE時刻符号]]、
[CODE(HTTP)@en[smpte-25][SMPTE時刻符号]]、
[CODE(HTTP)@en[[[npt]]]]、[CODE(HTTP)@en[clock][clock (RTSP)]]
が規定されています。

;; [12] これらは [CITE[[[Protocol for Media Fragments 1.0 Resolution in HTTP]]]]
で [[HTTP]] においても提案されていましたが、謎の接頭辞の仕組みが併用されています。

[10] [CODE(HTTP)@en[[[none]]]] は[[範囲単位]]ではありませんが、
[CODE(HTTP)@en[[[Accept-Ranges:]]]] で[[範囲単位]]のかわりに用いられます。
[[IANA]] にも予約として登録されています [SRC[>>14]]。

[17] [[HTTP]] ではどの[[範囲単位]]の実装も義務付けられていませんが、
[[鯖]]と[[キャッシュ]]は [CODE(HTTP)@en[[[bytes]]]] を実装する[RUBYB[べき]@en[ought to]]
[SRC[>>16]] とされています。大容量のファイルの送受信を行う[[利用者エージェント]]や[[鯖]]は、
実用上、 [CODE(HTTP)@en[[[bytes]]]] を実装する必要があります。

;; [20] 未対応の[[鯖]]は範囲の指定を無視するでしょうし、未対応の[[利用者エージェント]]はファイル全体を要求するだけでしょうから、
非効率的であるだけで実装しなくても構わないといえば構わないのですが。

* 濫用

[19] [[Heroku]] [[API]] [SRC[>>18]] は[[ページング]]のためのキーの指定のために[[範囲単位]]を濫用しています。

[REFS[
- [18] [CITE@en[Platform API Reference | Heroku Dev Center]] ([TIME[2014-10-08 12:28:43 +09:00]] 版) <https://devcenter.heroku.com/articles/platform-api-reference#ranges>
]REFS]

* メモ

[11] [CITE[ajax - Using the HTTP Range Header with a range specifier other than bytes? - Stack Overflow]]
( ([TIME[2014-09-17 02:47:06 +09:00]] 版))
<http://stackoverflow.com/questions/1434647/using-the-http-range-header-with-a-range-specifier-other-than-bytes>

[13] [CITE[Byte Rot: Using range header for retrieving range of IEnumerable<T> in ASP.NET Web API]]
( ([TIME[2014-09-04 13:25:18 +09:00]] 版))
<http://byterot.blogspot.jp/2012/07/range-header-asp-net-web-api-entity-pagination.html>

[FIG(quote)[
[FIGCAPTION[
[21] [CITE@en[Platform API Reference | Heroku Dev Center]]
([TIME[2017-02-11 14:47:15 +09:00]])
<https://devcenter.heroku.com/articles/platform-api-reference#ranges>
]FIGCAPTION]

> List requests will return a Content-Range header indicating the range of values returned. Large lists may require additional requests to retrieve. If a list response has been truncated you will receive a 206 Partial Content status and the Next-Range header set. To retrieve the next range, repeat the request with the Range header set to the value of the previous request’s Next-Range header.
> The number of values returned in a range can be controlled using a max key in the Range header. For example, to get only the first 10 values, set this header: Range: id ..; max=10;. max can also be passed when iterating over Next-Range. The default page size is 200 and maximum page size is 1000.
> The property used to sort values in a list response can be changed. The default property is id, as in Range: id ..;. To learn what other properties you can use to sort a list response, inspect the Accept-Ranges headers.

]FIG]


[FIG(quote)[
[FIGCAPTION[
[22] [CITE@en[Divide Large Responses Across Requests with Ranges · HTTP API Design]]
([[Wesley Beary]]著, [TIME[2017-02-10 22:07:15 +09:00]])
<https://geemus.gitbooks.io/http-api-design/content/en/foundations/divide-large-responses-across-requests-with-ranges.html>
]FIGCAPTION]

> Large responses should be broken across multiple requests using Range headers to specify when more data is available and how to retrieve it.

]FIG]
