[1] [DFN[[CODE(HTTP)@en[[[ETag:]]]]]] [[ヘッダー]]は、[[選択された表現]]の[[実体タグ]]を表します。

* 仕様書

[REFS[
- [11] '''[CITE@en[RFC 7232 - Hypertext Transfer Protocol (HTTP/1.1): Conditional Requests]] ([TIME[2014-09-11 10:02:44 +09:00]] 版) <https://tools.ietf.org/html/rfc7232#section-2.3>'''
- [47] [CITE@en[RFC 7232 - Hypertext Transfer Protocol (HTTP/1.1): Conditional Requests]] ([TIME[2014-09-11 10:02:44 +09:00]] 版) <https://tools.ietf.org/html/rfc7232#section-2.1>
- [21] [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.4.1>
- [23] [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-15>
-- [28] [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-15.6>
]REFS]

* 意味

[12] [CODE(HTTP)@en[[[ETag:]]]] [[ヘッダー]]は、[[選択された表現]]の、
[[要求]]の処理の完了の時点での[[実体タグ]]を表します [SRC[>>11]]。

[45] [[ヘッダー名]]の [CODE[ETag]] は、 [[entity-tag]] ([[実体タグ]]) の略です。
当該[[メッセージ]]に含まれる[[実体]]の[[実体タグ]]を表す[[ヘッダー]]であることからこの名前となっています。

[46] 
[[実体タグ]]については、[[実体タグ]]参照。

* 構文

[16] [CODE(HTTP)@en[[[ETag:]]]] [[ヘッダー]]の値は、
[[実体タグ]] ([CODE(ABNF)@en[[[entity-tag]]]]) です [SRC[>>11]]。

[FIG(railroad)[
= [[実体タグ]]
]FIG]

;; [49] [[実体タグ]]には [CH["]] も含まれています。

* 文脈

[48] [[起源鯖]]は、合理的かつ一貫的に変更を検出できる場合には、
[[選択された表現]]の [CODE(HTTP)@en[[[ETag:]]]] を送信する[['''べきです''']] [SRC[>>11]]。

[8] [[起源鯖]]は、 [CODE(HTTP)@en[[[GET]]]] や [CODE(HTTP)@en[[[HEAD]]]]
に対する [CODE(HTTP)[[[200]]]] [[応答]]では、
[CODE(HTTP)@en[[[ETag:]]]] も [CODE(HTTP)@en[[[Last-Modified:]]]]
も、送ることができるなら送る[['''べきです''']]。
性能上その他の理由で強い[[実体タグ]]より弱い[[実体タグ]]が好ましいなら、
それでも構いません。 [SRC[>>11]]

[55] 指定してはならない文脈については [CODE(HTTP)@en[[[If-Match:]]]]
の項を参照。

[22] [CODE(HTTP)[[[226]]]] [[応答]]は[[実体タグ]]を [CODE(HTTP)@en[[[ETag:]]]]
に含めなければ[['''なりません''']] [SRC[>>21]]。

[56] [CODE(HTTP)[[[304]]]] の項も参照。

[50] 
実世界では、いわゆる[[静的ファイル]]を返す[[サーバー]]は
[CODE[GET]] [[応答]]に [CODE[ETag:]] [[ヘッダー]]を含めることが多く、
[[動的]]な内容を返す[[アプリケーションサーバー]]は
[CODE[ETag:]] [[ヘッダー]]を含めないことが多いです。

;; [57] 
[[ファイルシステム]]上の[[ファイル]]を返す静的なサーバーでは[[ファイル]]の
[[iノード]]のような [CODE[ETag:]] の[[実体タグ]]に使いやすい情報がありますが、
動的サーバーではそのような適当な値がないことが多いためです。
[SEE[ [[実体タグ]] ]]


* 処理

[58] [CODE[ETag:]] で指定された[[実体タグ]]は、[[HTTPキャッシュ]]やそれに関連する[[条件付き要求]]などで使うことが出来ます。

[51] [[クライアント]]は、[[起源鯖]]が[[実体タグ]]を提供していたなら、
[[キャッシュ]]の[[検証]]を行う[[要求]]の
[CODE(HTTP)@en[[[If-Match:]]]] や [CODE(HTTP)@en[[[If-None-Match:]]]]
で[[実体タグ]]を送信しなければ[['''なりません''']] [SRC[>>11]]。

[52] [[クライアント]]は、[[起源鯖]]が [CODE(HTTP)@en[[[Last-Modified:]]]]
のみを提供していた場合に、[[キャッシュ]]の全部分の[[検証]]を行う[[要求]]の
[CODE(HTTP)@en[[[If-Modified-Since:]]]]
で [CODE(HTTP)@en[[[Last-Modified]]]] 値を送信する[['''べきです''']] [SRC[>>11]]。

[53] [[クライアント]]は、 [[HTTP/1.0]] [[起源鯖]]が [CODE(HTTP)@en[[[Last-Modified:]]]]
のみを提供していた場合に、[[キャッシュ]]の一部分の[[検証]]を行う[[要求]]の
[CODE(HTTP)@en[[[If-Unmodified-Since:]]]]
で [CODE(HTTP)@en[[[Last-Modified:]]]] 値を送信して[['''構いません''']] [SRC[>>11]]。
[[利用者エージェント]]は問題があった場合にこれを無効にする方法を用意する[['''べきです''']]
[SRC[>>11]]。

[54] [[クライアント]]は、[[起源鯖]]が[[実体タグ]]と [CODE(HTTP)@en[[[Last-Modified]]]]
の両方を提供していた場合に、[[キャッシュ]]の[[検証]]を行う[[要求]]に両方を含める[['''べきです''']]
[SRC[>>11]]。

* プライバシー

[15] [[実体タグ]]を参照。

* [CODE(URI)@en[DAV:getetag]] 特性 (WebDAV)

[29] [DFN[[CODE(URI)@en[[[DAV:getetag]]]]]] [[特性]]は、 [[accept header]]
なしで [CODE(HTTP)@en[[[GET]]]] したときに返されるであろう [CODE(HTTP)@en[[[ETag:]]]]
[[ヘッダー]]の値を表します [SRC[>>28]]。

[30] 値は[[実体タグ]]です [SRC[>>28]]。[CODE(HTTP)@en[[[ETag:]]]]
[[ヘッダー]]に [[OWS]] が含まれる場合でも、値にはこれを含める[['''べきではありません''']]
[SRC[>>23]]。

[31] この値は[[鯖]]が制御するもので、この[[特性]]は[[保護特性]]です [SRC[>>28]]。

[32] [CODE(HTTP)@en[[[COPY]]]] や [CODE(HTTP)@en[[[MOVE]]]]
の後は、終点資源の最終的な状態により値が決まります [SRC[>>28]]。

[33] [[WebDAV]] に従う[[資源]]で [CODE(HTTP)@en[[[ETag:]]]]
[[ヘッダー]]を返すものは、 [CODE(URI)@en[[[DAV:getetag]]]]
[[特性]]を定義しなければ[['''なりません''']] [SRC[>>28]]。

* 歴史

[2621] [CITE[Editing the Web - Detecting the Lost Update Problem Using Unreserved Checkout]]
( ([TIME[1999-05-11 06:02:12 +09:00]] 版))
<http://www.w3.org/1999/04/Editing/>

[2617] [CITE[Editing the Web - Detecting the Lost Update Problem Using Unreserved Checkout]] ([TIME[1999-05-11 07:02:58 +09:00]] 版) <http://www.w3.org/1999/04/Editing/01>

[FIG(quote)[
[FIGCAPTION[
[14] RFC [DEL(RFC2068)[2068]] [INS(RFC2616)[2616]] (HTTP/1.1) 14.[DEL(RFC2068)[20]][INS(RFC2616)[19]] ETag
]FIGCAPTION]

> The ETag [DEL(RFC2068)[entity]][INS(RFC2616)[response]]-header 
field [DEL(RFC2068)[defines]] [INS(RFC2616)[provides the current value of]] the
entity tag for the [DEL(RFC2068)[associated]] [INS(RFC2616)[requested]]
variant. The headers used with entity
tags are described in sections [DEL(RFC2068)[14.20, 14.25]] [INS(RFC2616)[14.24]], 14.26 and 
14.[DEL(RFC2068)[43]][INS(RFC2616)[44]]. The entity tag [DEL(RFC2068)[may]] [INS(RFC2616)[MAY]] 
be used for comparison with other entities from the same resource
(see section 13.3.[DEL(RFC2068)[2]][INS(RFC2616)[3]]).

[6] [CODE(HTTP)[ETag]]  [DEL(RFC2068)[実体]][INS(RFC2616)[応答]]頭欄は、 [DEL(RFC2068)[関連付けられ]][INS(RFC2616)[要求され]]た変種の[[実体札]][DEL(RFC2068)[を定義]][INS(RFC2616)[の現在値を提供]]します。
実体札とともに使う頭は[DEL(RFC2068)[14.20節, 14.25節]] [INS(RFC2616)[14.24節]], 14.26節, 
14.[DEL(RFC2068)[43]][INS(RFC2616)[44]]節  [INS[([[Vary:]>>11])]] で説明しているいます。
実体札は同じ資源のほかの実体との比較に使っても[DEL(RFC2068)[構いません]][INS(RFC2616)['''構いません''']]
(13.3.[DEL(RFC2068)[2]][INS(RFC2616)[3]]節参照)。

- [2]     [CODE(ABNF)[ETag = "ETag" ":" [[entity-tag]]]]

> Examples:

- [3] ETag: "xyzzy"
- [4] ETag: W/"xyzzy"
- [5] ETag: ""
]FIG]

[2618] [CITE@en[RFC 3143 - Known HTTP Proxy/Caching Problems]] ([TIME[2008-08-30 12:43:01 +09:00]] 版) <http://tools.ietf.org/html/rfc3143#appendix-A.2.3>

[2623] [CITE@en[RFC 7252 - The Constrained Application Protocol (CoAP)]]
( ([TIME[2014-06-27 00:59:37 +09:00]] 版))
<http://tools.ietf.org/html/rfc7252#section-5.10.6>

* 実装

[13] [CODE(HTTP)@en[[[ETag:]]]] は[[静的]]に[[ファイルシステム]]上のデータを提供する[[鯖]]が[[生成]]することが多いですが、
[[動的]]に生成されるページではあまり使われません。

[17] [[負荷分散]]その他の目的で複数の[[鯖]]から[[資源]]が供給される場合、
それらの [CODE(HTTP)@en[[[ETag:]]]] の精製方法が異なると、
[[キャッシュ]]が思うように動作しないことがあります。 [[Apache]]
などは既定の状態では[[ファイル]]の [[inode番号]]を [CODE(HTTP)@en[[[ETag:]]]]
を使うので、何の設定もしないと[[鯖]]ごとに同じファイルでも異なる
[CODE(HTTP)@en[[[ETag:]]]] が使われ、[[キャッシュ]]が機能しません。

[2619] [CITE[堀愚霊瑠の指摘で気付いた、はてなスターの静的ファイルとか想像以上にアレな件 - にぽたん研究所]] ([TIME[2009-02-08 18:44:24 +09:00]] 版) <http://blog.livedoor.jp/nipotan/archives/51186026.html>

[2620] [CITE[Squid 2.6.STABLE21 Configuration File: broken_vary_encoding]]
([TIME[2008-07-22 05:54:52 +09:00]] 版)
<http://www.squid-cache.org/Versions/v2/2.6/cfgman/broken_vary_encoding.html>

[2622] [CITE@en[Protocol Reference - Google Data APIs — Google Developers]]
( ([TIME[2012-07-12 01:21:59 +09:00]] 版))
<https://developers.google.com/gdata/docs/2.0/reference#ResourceVersioning>

* 例

[24] 次のような例が挙げられています [SRC[>>11]]。
[FIG(list)[
- [25] [CODE(HTTP)[ETag: "xyzzy"]]
- [26] [CODE(HTTP)[ETag: W/"xyzzy"]]
- [27] [CODE(HTTP)[ETag: ""]]
]FIG]

* メモ

[7] [CODE(HTTP)[[[201]]]] (作成済み) 応答では、
作成された[[資源]]についての実体札を [CODE(HTTP)[ETag]] 
頭欄に入れることができます。他の応答の場合 
[WEAK[(応答実体についての実体札。)]] とは異なるので注意が必要です。

[9]
[CITE[mnot’s Web log: ETags, ETags, ETags]] ([CODE[2007-08-09 23:20:31 +09:00]] 版) <http://www.mnot.net/blog/2007/08/07/etags>

[10]
[CITE@en[Sam Ruby: Etag vs Encoding]] ([TIME[2007-10-02 00:06:41 +09:00]] 版) <http://www.intertwingly.net/blog/2007/09/30/Etag-vs-Encoding>

[34] よくデータの同一性検査に [[MD5]] 値を使ったりしますが、それを一般的にしたようなものであると理解すれば良いでしょう。

[40] [CITE@en-gb-x-gsnedders[gsnedders / HTTP Entity Tags Confusion]] ([TIME[2007-10-29 08:34:13 +09:00]] 版) <http://gsnedders.com/http-entity-tags-confusion>

[2625] [CITE[8 Ways to Save Bandwidth on your RSS Feed]]
( ([[Peter Freitag]] 著, [TIME[2014-09-15 10:00:19 +09:00]] 版))
<http://www.petefreitag.com/item/642.cfm>

[2626] [CITE[DSAS開発者の部屋:負荷分散環境でブラウザキャッシュが効かないときは - ETagの解説 -]]
( ([TIME[2014-09-15 10:27:33 +09:00]] 版))
<http://dsas.blog.klab.org/archives/50602499.html>

[2627] [CITE@en[Platform API Reference | Heroku Dev Center]]
( ([TIME[2014-10-08 12:22:59 +09:00]] 版))
<https://devcenter.heroku.com/articles/platform-api-reference#data-integrity>

[2628] [CITE[PublisherEfficiency - pubsubhubbub - How to maximize the efficiency of publishing Atom feeds - A simple, open, webhook based pubsub protocol & open source reference implementation. - Google Project Hosting]]
( ([TIME[2014-11-20 01:50:53 +09:00]] 版))
<https://code.google.com/p/pubsubhubbub/wiki/PublisherEfficiency#Feed_windowing>

[18] [CITE@en[Sam Ruby: Vary: ETag]] ([TIME[2014-11-19 08:28:19 +09:00]] 版) <http://www.intertwingly.net/blog/2004/09/11/Vary-ETag>

[FIG(quote)[
[FIGCAPTION[
[35] [CITE@en[Hashes and ETags: Best Practices - Cloud Storage — Google Cloud Platform]]
([TIME[2015-05-27 08:55:19 +09:00]] 版)
<https://cloud.google.com/storage/docs/hashes-etags>
]FIGCAPTION]

> Historically, an object’s MD5 was expressed via the ETag header. This behavior will continue for non-composite objects in the XML API, but since composite objects don’t support MD5 hashes, users should make no assumptions about those ETags except that they will change whenever the underlying data changes, per the IETF specification for HTTP/1.1.

]FIG]


[36] [CITE@en[Linked Data Platform Paging 1.0]]
([TIME[2015-07-01 15:11:45 +09:00]] 版)
<https://dvcs.w3.org/hg/ldpwg/raw-file/default/ldp-paging.html#h-ldpr-notify-changes>

[37] [CITE@en[RFC 8132 - PATCH and FETCH Methods for the Constrained Application Protocol (CoAP)]]
([TIME[2017-04-07 10:01:21 +09:00]])
<https://tools.ietf.org/html/rfc8132#section-2.3.2>

[FIG(quote)[
[FIGCAPTION[
[38] [CITE@en[RFC 4791 - Calendaring Extensions to WebDAV (CalDAV)]]
([TIME[2017-09-24 16:22:36 +09:00]])
<https://tools.ietf.org/html/rfc4791#section-2>
]FIGCAPTION]

>    o  MUST support ETags '''['''RFC2616''']''' with additional requirements
>       specified in Section 5.3.4 of this document;
> 

]FIG]


[39] [CITE@en[RFC 4791 - Calendaring Extensions to WebDAV (CalDAV)]]
([TIME[2017-09-24 16:22:36 +09:00]])
<https://tools.ietf.org/html/rfc4791#section-5.3.4>

[41] [CITE[RFC Errata Report » RFC Editor]]
([TIME[2017-10-01 21:28:40 +09:00]])
<https://www.rfc-editor.org/errata_search.php?rfc=4791>

[42] [CITE[curl - How To Use]]
([TIME[2020-09-21T09:01:13.000Z]], [TIME[2020-10-01T06:10:13.192Z]])
<https://curl.haxx.se/docs/manpage.html#--etag-compare>