[41] [DFN[[CODE(HTTP)@en[[[If:]]]]]] [[ヘッダー]]は、[[状態トークン]]と[[実体タグ]]によって[[要求]]の適用条件を指定するものです。

* 仕様書

[REFS[
- [1] [CITE@en[RFC 4918 - HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)]] ([TIME[2014-09-21 17:04:59 +09:00]] 版) <http://tools.ietf.org/html/rfc4918#section-6.1>
- [3] [CITE@en[RFC 4918 - HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)]] ([TIME[2014-09-21 17:04:59 +09:00]] 版) <http://tools.ietf.org/html/rfc4918#section-7.4>
- [5] [CITE@en[RFC 4918 - HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)]] ([TIME[2014-09-21 17:04:59 +09:00]] 版) <http://tools.ietf.org/html/rfc4918#section-7.5>
- [38] [CITE@en[RFC 4918 - HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)]] ([TIME[2014-09-21 17:04:59 +09:00]] 版) <http://tools.ietf.org/html/rfc4918#section-7.7>
- [37] [CITE@en[RFC 4918 - HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)]] ([TIME[2014-09-21 17:04:59 +09:00]] 版) <http://tools.ietf.org/html/rfc4918#section-9.10>
- [8] '''[CITE@en[RFC 4918 - HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)]] ([TIME[2014-09-21 17:04:59 +09:00]] 版) <http://tools.ietf.org/html/rfc4918#section-10.4>'''
- [33] [CITE@en[RFC 4918 - HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)]] ([TIME[2014-09-21 17:04:59 +09:00]] 版) <http://tools.ietf.org/html/rfc4918#section-12.1>
]REFS]

* 意味

[10] [CODE(HTTP)@en[[[If:]]]] [[ヘッダー]]は、
トークンと[[実体タグ]]が特定の[[資源]]と一致するかどうかの条件の状態リストを指定して[[要求]]を[[条件付き]]とするために使うことができます [SRC[>>8]]。

[11] [CODE(HTTP)@en[[[If:]]]] [[ヘッダー]]は、
[[状態トークン]]を指定して、[[クライアント]]が[[状態トークン]]についての知識を有することを示すためにも使うことができます [SRC[>>8]]。
[[状態トークン]]を [CODE(HTTP)@en[[[If:]]]] に指定することを[DFN[[RUBYB[[[提出]]]@en[submit]]]]といいます [SRC[>>1, >>8]]。

;; [2] その意味は[[状態トークン]]の種類によって異なります [SRC[>>8]] が、
[[ロックトークン]]の場合、[[クライアント]]の [[principal]] が[[ロック]]を有すると表明することとなります。

[12] >>10 と >>11 は同じ[[ヘッダー]]に記述されますが、別々に処理されます。
[[状態トークン]]が[[提出]]されたとみなすかどうかと、
[[状態トークン]]が含まれる状態リストを[[鯖]]が実際に評価したか否かや、
含まれる条件が[[真]]に評価されるか否かは、独立しています [SRC[>>8]]。

* 構文

[15] [CODE(HTTP)@en[[[If:]]]] [[ヘッダー]]の値は、
1つ以上のタグ無しリストの [[OWS]] 区切りのリスト、
または1つ以上のタグ付きリストの [[OWS]] 区切りのリストです [SRC[>>8]]。

[FIG(railroad)[
= |
== =
=== タグ無しリスト
=== *
==== [[OWS]]
==== タグ無しリスト
== =
=== タグ付きリスト
=== *
==== [[OWS]]
==== タグ付きリスト
]FIG]

;; タグ付きリストとタグ無しリストを混在させることはできません。

[24] [CODE(HTTP)@en[[[If:]]]] [[ヘッダー]]は、含まれるタグ付きリストやタグ無しリストのいずれかが[[真]]と評価されるなら全体として[[真]]であり、
すべてが[[偽]]と評価されるなら全体として[[偽]]となります [SRC[>>8]]。

[16] タグ無しリストは、1つ以上の条件を [CODE[[[(]]]] と [CODE[[[)]]]] で括ったものです 
[SRC[>>8]]。条件の前後には [[OWS]] を挿入できるようです。

[FIG(railroad)[
= [CODE(HTTP)[[[(]]]]
= [[OWS]]
= 条件
= *
== [[OWS]]
== 条件
= [[OWS]]
= [CODE(HTTP)[[[)]]]]
]FIG]

[17] タグ付きリストは、1つ以上のタグ無しリストの前に資源タグを置いたものです [SRC[>>8]]。
資源タグの後やリスト間には [[OWS]] を挿入できるようです。
資源タグは、[[単純参照]]を [CODE[[[<]]]] と [CODE[[[>]]]] で括ったものです [SRC[>>8]]。

[FIG(railroad)[
= [CODE(HTTP)[[[<]]]]
= [[単純参照]]
= [CODE(HTTP)[[[>]]]]
= [[OWS]]
= リスト
= *
== [[OWS]]
== リスト
]FIG]

[20] タグ付きリストは、リストが資源タグの [[URL]] についてのものであることを表しています。
タグ無しリストは、リストが[[要求URL]]についてのものであることを表しています。 [SRC[>>8]]

[22] タグ付きリスト内の各リストやタグ無しリストは、
含まれる条件がすべて[[真]]であるなら全体として[[真]]で、
[[偽]]のものがあるなら全体として[[偽]]となります [SRC[>>8]]。

[23] タグ付きリストは、含まれるリストのいずれかが[[真]]であるなら全体として[[真]]で、
すべて[[偽]]であるなら全体として[[偽]]となります [SRC[>>8]]。

[18] 条件は、[[状態トークン]]か[[実体タグ]]か、それらの前に 
[CODE(HTTP)[[[Not]]]] を置いたものです。
[[状態トークン]]は[[絶対URL]]を [CODE[[[<]]]] と [CODE[[[>]]]] で括ったものです。
[[実体タグ]]は [CODE[''['']] と [CODE['']'']] で括ります。
[CODE(HTTP)[[[Not]]]] は[[大文字・小文字不区別]]です。 [SRC[>>8]]
[CODE(HTTP)[[[Not]]]] の前後には [[OWS]] を挿入できるようです。

[FIG(railroad)[
= ?
== [CODE(HTTP)[[[Not]]]]
== [[OWS]]
= |
== =
=== [CODE[[[<]]]]
=== [[ASCII絶対URL]]
=== [CODE[[[>]]]]
== =
=== [CODE[''['']]
=== [[実体タグ]]
=== [CODE['']'']]
]FIG]

;; [19] [[絶対URL]]の定義としては [[RFC 3986]] [CODE(ABNF)@en[[[absolute-URI]]]]
が参照されています [SRC[>>8]]。

[21] [DFN[[CODE(HTTP)@en[[[Not]]]]]] は条件の否定を表しています [SRC[>>8]]。

* 文脈

[34] 任意の[[要求]]が [CODE(HTTP)@en[[[If:]]]] [[ヘッダー]]を含めることができます [SRC[>>33]]。

[6] 変更される[[資源]]が複数ある場合は、関係するすべての[[ロック]]の[[ロックトークン]]を[[提出]]しなければ[['''なりません''']] [SRC[>>5]]。

[EG[
[7] 例えば移動時に移動元と移動先の両方が[[ロック]]されているなら、
両方の[[ロックトークン]]が必要です [SRC[>>5]]。
]EG]

[4] 変更しようとする[[資源]]が[[コレクション]]の[[メンバー]]として間接的に[[ロック]]されている時は、
(直接の[[ロック]]とは別に) [[コレクション]]の[[ロックトークン]]も指定する必要があります [SRC[>>3]]。

[39] [[ロック]]を更新するために [CODE(HTTP)@en[[[LOCK]]]] [[要求]]に
[CODE(HTTP)@en[[[If:]]]] [[ヘッダー]]を指定することができます。その場合、
[[ロックトークン]]は1つだけ指定しなければ[['''なりません''']]。 [SRC[>>38, >>37]]

[29] [[WebDAV]] に対応しない[[串]]は [CODE(HTTP)@en[[[If:]]]] を扱えないでしょうから、
[[HTTP/1.1]] [[串]]への[[要求]]には [CODE(HTTP)@en[[[Cache-Control:]] [[no-cache]]]] を、
[[HTTP/1.0]] [[串]]への[[要求]]には [CODE(HTTP)@en[[[Pragma:]] [[no-cache]]]]
を含めなければ[['''なりません''']] [SRC[>>8]]。
一般に [[WebDAV]] に対応していない[[串]]を判定する信頼できる方法はありませんから、
常に指定するのが[RUBYB[良い]@en[advised]] [SRC[>>8]] とされています。

* 処理

[14] [CODE(HTTP)@en[[[If:]]]] [[ヘッダー]]が[[偽]]と評価された場合には、
[CODE(HTTP)[[[412]]]] [[応答]]を返して失敗としなければ[['''なりません''']] [SRC[>>8, >>33]]。
そうでない場合には、 [CODE(HTTP)@en[[[If:]]]] [[ヘッダー]]が無かった場合のように処理を続行できます [SRC[>>8]]。

[25] [[実体タグ]]は、指定された[[資源]]の[[実体タグ]]と ([[強い比較]]または[[弱い比較]]で)
一致するかどうかを評価します [SRC[>>8]]。

[26] [[状態トークン]]は、指定された[[資源]]に関する[[状態トークン]]と完全一致で比較します。
[[ロックトークン]]の場合には、[[資源]]が[[ロック]]の適用範囲内にあれば一致とします。 [SRC[>>8]]

[27] なお指定された[[資源]]が[[写像]]されていない [[URL]] の場合には、
[[実体タグ]]も[[状態トークン]]も一致しないものとします [SRC[>>8]]。

;; [28] [[ロック]]の適用範囲内となる場合でも特別扱いはしていないようです。

[13] 関係するすべての[[ロック]]の[[ロックトークン]]が指定されなかった場合は、
変更操作が失敗しなければ[['''なりません''']]。 [SRC[>>5]]

[40] [CODE(HTTP)@en[[[LOCK]]]] [[要求]]に [CODE(HTTP)@en[[[If:]]]] 
が指定された場合で[[対象資源]]がその範囲内にない場合には、 
[CODE(HTTP)[[[412]]]] [[応答]]を返すことができます。
[[応答]]には[[事前条件符号]] [CODE(XMLe)@en[[[lock-token-matches-request-uri]]]]
を指定できます。 [SRC[>>37]]

* 歴史

[36] [[IANA登録簿]]は [[RFC 4918]] が出典に更新されています [SRC[>>35]]。

[REFS[
- [35] [CITE@en[RFC 4918 - HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)]] ([TIME[2014-09-21 17:04:59 +09:00]] 版) <http://tools.ietf.org/html/rfc4918#section-21.3.1>
]REFS]

* 例

[EG[
[30] 
[PRE(HTTP code)[
If: (<urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2>
  ["I am an ETag"])
  (["I am another ETag"])
]PRE]
... は、
[FIG(list)[
- [[対象資源]]が[[ロックトークン]] <urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2>
の[[ロック]]の適用範囲内にあって[[実体タグ]] [CODE["I am an ETag"]]
を有している
- [[対象資源]]が[[実体タグ]] [CODE["I am another ETag"]] を有している
]FIG]
... のいずれかであることを求めています [SRC[>>8]]。
]EG]

[EG[
[31] 
[PRE(HTTP code)[
If: (Not <urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2>
  <urn:uuid:58f202ac-22cf-11d1-b12d-002035b29092>)
]PRE]
... は、1つ目の [[URL]] の[[ロック]]の対象ではなく、かつ
2つ目の [[URL]] の[[ロック]]の対象であることを求めています [SRC[>>8]]。
]EG]

[EG[
[32] 
[PRE(HTTP code)[
If: (<urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2>)
  (Not <DAV:no-lock>)
]PRE]
... は、 [CODE(URI)[[[DAV:no-lock]]]] が[[ロックトークン]]として使われることのない [[URL]]
であり、その否定形は常に[[真]]となるため、[[ヘッダー]]全体として常に[[真]]に評価されます。
[[ロック]]がタイムアウトで無効となっても失敗せずに処理を続けさせたい場合にこのような指定が有用です。 [SRC[>>8]]
]EG]

* 関連

[9] [CODE(HTTP)@en[[[If-Match:]]]] [[ヘッダー]]と似ていますが、
[CODE(HTTP)@en[[[If:]]]] [[ヘッダー]]には[[実体タグ]]の他に[[状態トークン]]も指定できる点が違っています。

[42] [CITE@ja[サポート切れの「IIS 6」でリモートから任意のコードが実行できるという脆弱性が発見される | スラド セキュリティ]]
([TIME[2017-04-05 20:38:09 +09:00]])
<https://security.srad.jp/story/17/04/05/0637251/>