-
Notifications
You must be signed in to change notification settings - Fork 4
/
619.txt
195 lines (168 loc) · 13.2 KB
/
619.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
[2] [CODE(HTTP)@en[[[Range:]]]] が指定された[[要求]]を、[DFN[[RUBYB[[[範囲要求]]]@en[range request]]]]といいます。
[[範囲要求]]を使うと[[資源]]の一部分のみを[[バイト]]単位で指定して受信できます。
* 仕様書
[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>
-- [14] [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>
-- [61] [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-4.1>
-- [5] [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-4.3>
-- [40] [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-6.1>
- [81] [CITE@en[RFC 7234 - Hypertext Transfer Protocol (HTTP/1.1): Caching]] ([TIME[2014-09-11 10:19:59 +09:00]] 版) <https://tools.ietf.org/html/rfc7234#section-3.3>
- [86] [CITE@en[RFC 3229 - Delta encoding in HTTP]] ([TIME[2014-10-26 21:15:25 +09:00]] 版) <http://tools.ietf.org/html/rfc3229#section-10.1>
]REFS]
* プロトコル
[4] [[範囲要求]]は次の[[プロトコル要素]]により構成されます。
[FIG(list short)[
- [CODE(HTTP)@en[[[Range:]]]]
- [CODE(HTTP)@en[[[If-Range:]]]]
- [[範囲単位]]
- [CODE(HTTP)@en[[[Accept-Ranges:]]]]
- [CODE(HTTP)[[[206]]]]
- [CODE(HTTP)[[[416]]]]
- [CODE(HTTP)@en[[[Content-Range:]]]]
- [CODE(MIME)@en[[[multipart/byteranges]]]]
]FIG]
[85] [[範囲要求]]は [CODE(HTTP)@en[[[GET]]]] [[要求]]にのみ適用されます。
他の[[要求メソッド]]では使えません。
* 処理モデル
[3] [[範囲要求]]への対応は必須ではありません [SRC[>>1]]。[[範囲要求]]を受信した時、
これに対応していない場合は、通常の [CODE(HTTP)@en[[[GET]]]]
[[要求]]として処理して構いません [SRC[>>1]]。
[84] [[HTTP鯖]]の処理全体における位置付けは [[HTTP鯖]]の項を、
[[キャッシュ]]における取り扱い全体は[[キャッシュ項目]]の項を、
[[実現値操作]]との関係は[[実現値操作]]の項を参照してください。
** 範囲要求への応答
[42] [[鯖]]は、[[範囲要求]]を次のように処理しなければなりません。
[FIG(steps)[
= [41] [[条件付き要求]]なら、[[条件付き要求]]の処理の規定に従い条件を評価します。
それによって[[応答]]が決まるなら、ここで終わります。
= [45] [[鯖]]が [CODE(HTTP)@en[[[Range:]]]] [[ヘッダー]]に対応しないなら、
ここで終わり通常の方法で処理します [SRC[>>14]]。
= [43] [CODE(HTTP)@en[[[Range:]]]] [[ヘッダー]]がなければ、
[[範囲要求]]ではないので、ここで終わり通常の方法で処理します。
= [44] [[要求メソッド]]が [CODE(HTTP)@en[[[GET]]]] 以外なら、
[CODE(HTTP)@en[[[Range:]]]] [[ヘッダー]]は無視します [SRC[>>14]]。
ここで終わり通常の方法で処理します。
= [46] [CODE(HTTP)@en[[[Range:]]]] [[ヘッダー]]の[[範囲単位]]が対応しないものなら、
== [47] [[起源鯖]]は、 [CODE(HTTP)@en[[[Range:]]]] [[ヘッダー]]を無視します [SRC[>>14]]。
== [48] [[串]]は、 [CODE(HTTP)@en[[[Range:]]]] [[ヘッダー]]を捨てても構いません [SRC[>>14]]。
== [49] いずれにせよ、ここで終わり通常の方法で処理します。
= [53] [CODE(HTTP)@en[[[Range:]]]] [[ヘッダー]]の値を[[範囲単位]]ごとの構文に従い解釈します。
= [54] 3つ[[以上]]の重複する範囲を含む [CODE(HTTP)@en[[[Range:]]]]
[[ヘッダー]]や、多数の[[昇順]]でない小さな範囲を指定した [CODE(HTTP)@en[[[Range:]]]]
[[ヘッダー]]を無視したり、拒絶したりして構いません [SRC[>>14]]。
=- [55] これらを送信した[[クライアント]]は壊れているのかもしれませんし、
[[DoS攻撃]]かもしれません。 [SRC[>>14, >>40]]
== [56] 拒絶する場合は、 [CODE(HTTP)[[[416]]]] [[応答]]を返してここで終わります。
== [57] 無視する場合は、ここで終わり通常の方法で処理します。
= [60] 指定された範囲が[[非妥当]]か[[満足不能]]なら、
[CODE(HTTP)[[[416]]]] [[応答]]を返してここで終わります [SRC[>>14]]。
= [59] 指定された範囲が[[妥当]]で[[満足可能]]なら、
[[満足可能]]な[[範囲]]に対応する1つ以上の部分[[表現]]を含む [[payload]]
をもった [CODE(HTTP)[[[206]]]] [[応答]]を送信します [SRC[>>14]]。
== [71] 複数の範囲が指定されていた場合に、範囲の指定の順序に関わらず、
重なり合う範囲をまとめたり、 [[multipart]]
による[[オーバーヘッド]]より隙間が小さいときにまとめたりしても構いません。 [SRC[>>61]]
==- [72] 一般的には [CODE(MIME)@en[[[multipart/byteranges]]]] の[[オーバーヘッド]]は
80バイト程度です。 [SRC[>>61]]
==- [73] >>54 の [[DoS攻撃]]への対策にもなります。
== [75] [CODE(MIME)@en[[[multipart/byteranges]]]] を使うか判断します。
=== [76] [CODE(HTTP)@en[[[Range:]]]] [[ヘッダー]]で指定された範囲が1つの時は、
使用しません [SRC[>>61]]。
=== [77] >>71 の場合は、どちらでも構いません [SRC[>>61]]。
=== [78] それ以外の場合は、使用します [SRC[>>61]]。
== [63] [CODE(MIME)@en[[[multipart/byteranges]]]] を使用する時は、
=== [66] 各範囲を[[本体部分]]とする [CODE(MIME)@en[[[multipart/byteranges]]]] を
[[payload]] に含めます [SRC[>>61]]。
==== [68] 範囲を指定した [CODE(HTTP)@en[[[Content-Range:]]]]
[[ヘッダー]]を[[本体部分]]に含めます [SRC[>>61]]。
==== [70] [[選択された表現]]が [CODE(HTTP)[[[200]]]] [[応答]]だった場合の[[応答]]の
[CODE(HTTP)@en[[[Content-Type:]]]] [[ヘッダー]]と同じ値の
[CODE(HTTP)@en[[[Content-Type:]]]] [[ヘッダー]]を[[本体部分]]に含める[['''べきです''']]
[SRC[>>61]]。
==== [69] 範囲のデータを[[本体部分]]の[[実体本体]]に含めます。
==- [74] [[満足不能]]な[[範囲]]や他の[[範囲]]とまとめた場合 (>>71) を除き、
[CODE(HTTP)@en[[[Range:]]]] に指定された順序で[[本体部分]]を並べる[['''べきです''']] [SRC[>>61]]。
==- [67] [[応答]]の[[ヘッダー]]としては [CODE(HTTP)@en[[[Content-Range:]]]]
を[[生成]]しては[['''なりません''']] [SRC[>>61]]。
== [62] それ以外の場合、
=== [64] 範囲を指定した [CODE(HTTP)@en[[[Content-Range:]]]]
[[ヘッダー]]を[[生成]]します [SRC[>>61]]。
=== [65] 範囲のデータを [[payload]] に含めます [SRC[>>61]]。
]FIG]
;; [51] [CODE(HTTP)@en[[[Range:]]]] [[ヘッダー]]が複数指定された時の動作は規定されていません。
;; [58] [CODE(HTTP)@en[[[Range:]]]] [[ヘッダー]]の値が構文的に正しくない場合の動作は規定されていません。
;; [52] [[起源鯖]]と中間[[キャッシュ]]は可能なら[[バイト範囲]]に対応する[RUBYB[べき]@en[ought to]]です [SRC[>>14]]。
;; [50] >>60 と >>59 はなぜか [['''MUST''']] ではなく [['''SHOULD''']]
です [SRC[>>14]]。 >>54 や >>45 の場合を考慮してなのかもしれませんが、
説明がないのでよくわかりません。また妥当・満足可能な範囲と非妥当・満足不能な範囲が混在する時、
どちらを返すべきかは不明瞭です。
;; [79] [CODE(HTTP)[[[206]]]] や [CODE(HTTP)[[[416]]]] の[[応答]]の[[ヘッダー]]については、
それぞれの項も参照してください。
** 部分応答の結合
[7] [[クライアント]]は、
[[HTTP接続]]が閉じられるのが早すぎた場合 ([[不完全]]な [CODE(HTTP)[[[200]]]] [[応答]])や、
[[範囲要求]]によって[[応答]]を得た場合 ([CODE(HTTP)[[[206]]]] [[応答]]) に、
同じ[[強い検証子]]を持っていればそれらを安全に組み合わせることができます [SRC[>>5, >>81]]。
[8] 結合した[[応答]]は次のように決めます。
[FIG(steps)[
= [13] 蓄積されている[[応答]]と新しい[[応答]]で[[強い検証子]]が一致するもの
([CODE(HTTP)[[[200]]]] [[応答]]と [CODE(HTTP)[[[206]]]] [[応答]]) を集めます。
= [10] 集めた[[応答]]のいずれかが [CODE(HTTP)[[[200]]]] [[応答]]なら、
== [20] 最新の [CODE(HTTP)[[[200]]]] [[応答]]の各[[ヘッダー]]を結合した[[応答]]の[[ヘッダー]]とします。 [SRC[>>51]]
== [82] [[警告符号]]が [CODE(HTTP)[[[1xx]]]] の [CODE(HTTP)@en[[[Warning:]]]]
[[ヘッダー]]があれば、削除します。 [SRC[>>81]]
= [21] そうでない場合 (いずれも [CODE(HTTP)[[[206]]]] [[応答]]の場合)、
== [22] 蓄積されている最新の[[応答]]の各[[ヘッダー]]を結合した[[応答]]の[[ヘッダー]]とします。
[SRC[>>51]]
== [23] 新しい[[応答]]の[[ヘッダー]]で結合した[[応答]]の各[[ヘッダー]]で結合した[[応答]]の[[ヘッダー]]を置き換えます。ただし [CODE(HTTP)@en[[[Content-Range:]]]] [[ヘッダー]]は除きます。
[SRC[>>51, >>81]]
== [83] [[警告符号]]が [CODE(HTTP)[[[1xx]]]] の [CODE(HTTP)@en[[[Warning:]]]]
[[ヘッダー]]があれば、削除します。 [SRC[>>81]]
= [39] 集めた[[応答]]から元のデータの復元を試みます。
= [15] データの全体が復元できた場合、
== [9] 結合した[[応答]]の[[状態符号]]は [CODE(HTTP)[[[200]]]] とします。 [SRC[>>5]]
== [12] 結合した[[応答]]の [CODE(HTTP)@en[[[Content-Length:]]]]
[[ヘッダー]]は得られたデータの長さとします。 [SRC[>>5]]
== [38] 結合した[[応答]]の [CODE(HTTP)@en[[[Transfer-Type:]]]] [[ヘッダー]]は適切に設定します。
== [27] 結合した[[応答]]の [CODE(HTTP)@en[[[Transfer-Encoding:]]]] [[ヘッダー]]は削除します。
== [16] 結合した[[応答]]の[[メッセージ本体]]は得られたデータとします。
= [19] 全体にはならなかった場合、
== [18] 得られたデータが元のデータの最初の部分だった時は、次のようにして構いません。
=== [24] 結合した[[応答]]の[[状態符号]]は [CODE(HTTP)[[[200]]]] とします。 [SRC[>>5]]
=== [25] 結合した[[応答]]の [CODE(HTTP)@en[[[Content-Length:]]]]
[[ヘッダー]]は得られたデータの長さとします。 [SRC[>>5]]
=== [37] 結合した[[応答]]の [CODE(HTTP)@en[[[Transfer-Type:]]]] [[ヘッダー]]は適切に設定します。
=== [28] 結合した[[応答]]の [CODE(HTTP)@en[[[Transfer-Encoding:]]]] [[ヘッダー]]は削除します。
=== [26] 結合した[[応答]]の[[メッセージ本体]]は得られたデータとします。
== [29] そうしない場合、次のようにして構いません。
=== [17] 結合した[[応答]]の[[状態符号]]は [CODE(HTTP)[[[206]]]] とします。 [SRC[>>5]]
=== [11] 結合した[[応答]]の[[メッセージ本体]]は得られたデータの各連続部分を含む
[CODE(MIME)@en[[[multipart/byteranges]]]] [[実体]]とします。 [SRC[>>5]]
=== [30] 結合した[[応答]]の [COD(HTTP)@en[[[Content-Type:]]]],
[CODE(HTTP)@en[[[Content-Length:]]]] は適当に設定し、
[CODE(HTTP)@en[[[Content-Range:]]]], [CODE(HTTP)@en[[[Transfer-Encoding:]]]]
は削除します。
== [31] そうしない場合、得られたデータの各連続部分について、
=== [32] 結合した[[応答]]の複製を用意します。
=== [33] その[[状態符号]]は [CODE(HTTP)@en[[[206]]]] とします。 [SRC[>>5]]
=== [34] その[[メッセージ本体]]はデータの連続部分とします。 [SRC[>>5]]
=== [35] その [CODE(HTTP)@en[[[Content-Range:]]]] [[ヘッダー]]を適切に設定します。 [SRC[>>5]]
=== [36] その [CODE(HTTP)@en[[[Content-Type:]]]] [[ヘッダー]]と
[CODE(HTTP)@en[[[Content-Length:]]]] [[ヘッダー]]を適切に設定し、
[CODE(HTTP)@en[[[Transfer-Encoding:]]]] [[ヘッダー]]は削除します。
]FIG]
;; [80] [[不完全メッセージ]]も参照。
;; [90] [CODE(HTTP)[[[304]]]] の場合の処理モデル ([[応答]]と[[ヘッダー]]の結合方法)
と似ています。 [CODE(HTTP)[[[226]]]] でも同様の方法が使われます。
* 実現値操作 [CODE(HTTP)@en[range]]
[87] [[実現値操作]] [DFN[[CODE(HTTP)@en[[[range]]]]]] は、
結果が[[範囲]]選択の結果としての部分内容であることを表します [SRC[>>86]]。
;; [89] [[IANA登録簿]]にも [[RFC 3229]] より登録されています [SRC[>>88]]。
[REFS[
- [88] [CITE[Instance Manipulation Values]] ([TIME[2014-01-31 02:45:13 +09:00]] 版) <http://www.iana.org/assignments/inst-man-values/inst-man-values.xhtml>
]REFS]
* メモ
[6] [CITE[http - Paging in a Rest Collection - Stack Overflow]]
( ([TIME[2014-09-17 02:47:22 +09:00]] 版))
<http://stackoverflow.com/questions/924472/paging-in-a-rest-collection>