last-modified

Last-Modified: ヘッダー (HTTP)

[6] Last-Modified: ヘッダーは、 応答に含まれる表現の最終変更日時を表します。

仕様書

意味

[9] Last-Modified: ヘッダーは、 起源鯖要求の処理の完了の時点において選択された表現が最後に変更されたと信ずる日時を表します >>5

[47] 何をもって最終変更日時とするかは著者の判断に委ねられるところであり、 意味的には若干の曖昧性があります。ファイルシステム上のファイル応答として使う (静的ファイルを提供する) サーバーでは、ファイルシステム上の更新日時を使うのが普通です。 しかし動的に生成される場合、複数の情報源 (データベース等) のデータを組み合わせて応答を作成することが多く、 何をもって最終変更日時とするべきかは定かではありません。その応答の作成の時刻 (つまり Date: と同じ時刻) かもしれませんが、 それならそれを明示しても意味が無い場合もあるかもしれません。

[48] 例えばファイルシステム上のファイル広告を差し込んで応答とする場合は、 ファイルシステム上のファイルの更新日時を使うべきで、差し込んだ日時を使うべきではないかもしれません。 しかし著者がその広告が当該ページの重要なコンテンツを形成するとみなすなら、 ファイル広告の新しい方の日時を使うべきかもしれません。

[49] 何が最終変更日時か著者にとっても明確でない時や、 Date: と同じにするしかなく、それには意味が無いと著者が考えるときは、 省略するべきでしょう。本ヘッダーは必須ではありません。

[50] 例えばデータベースから無作為に選択した内容を表示するときは、 本ヘッダーは省略した方が良いかもしれません。

構文

[10] Last-Modified: ヘッダーの値は、 HTTP-date です >>5

文脈

[12] 起源鯖は、選択された表現の最終修正日時が合理的かつ一貫的に決定できるなら、 Last-Modified: を送信するべきです >>5。 その値はできるだけ応答Date: ヘッダー生成する時刻の近くの時点で得るべきです >>5

[13] 表現はいくつかの部分を組み合わせて構成されることがよくありますが、 その場合それらのうちで最も直近に変更されたものの日時が最終修正日時となるのが普通です。 >>5

[14] 時計を持つ起源鯖は、 Date: より後の Last-Modified: を送信してはなりません >>5メタデータによると時計よりも後の最終修正日時となるような場合には、 Date: の値で置き換えなければなりません >>5

[15] これはキャッシュ検証への悪影響を避けるためです >>5

[16] 時計を持たない起源鯖は、他の信頼できる時計を持つシステムや利用者が指定している場合を除き、 Last-Modified: を設定してはなりません >>5

[27] ETag: の項も参照。

[28] 指定してはならない文脈については If-Match: の項を参照。

[29] 304 の項も参照。

タイムスタンプ

[32] WebDAV 資源本体URL が変わっていないならタイムスタンプを変えるべきではありません >>31

[34] WebDAV は、 (COPYMOVE などの URL を操作するメソッドの結果であろうと、) GET が返すであろうものが変わる度にタイムスタンプを (その精度内で) 変更しなければなりません>>33

[35] 場合によっては、移動・複製した範囲に含まれる複数の資源タイムスタンプを更新しないといけないかもしれません >>33
[36] 移動でタイムスタンプが更新されるのは必ずしも利用者の意図 (や多くのファイルシステムの実装方法) ではない気がしますが...

処理

[17] Last-Modified: ヘッダーの値が強い検証子弱い検証子かは、 次のように決定できます >>5

  1. [18] 起源鯖が現在の実際の検証子と比較する場合は、 当該表現は元の検証子で示されたに2度変更されていないと断言できるなら、 強い検証子です。
  2. [19] クライアントが当該表現キャッシュ項目を有しており、 検証子If-Modified-Since:If-Unmodified-Since:If-Range: に指定しようとする場合で、そのキャッシュDate: が含まれており、 Last-Modified:Date: より60秒以上前の場合には、強い検証子です。
  3. [20] 中間キャッシュが当該表現キャッシュ項目を有しており、 その検証子と比較する場合で、そのキャッシュDate: が含まれており、 Last-Modified:Date: より60秒以上前の場合には、強い検証子です。
  4. [21] それ以外の場合、弱い検証子です。

[22] この判定方法は、もし起源鯖が同じに2回異なる応答を返していて、 そのどちらも同じ Last-Modified: の値だったとすると、 少なくても一方の Date:Last-Modified: と一致するはず、という性質によっています。60秒としているのは Date:Last-Modified: が異なる時計から得られた場合などを想定しており、 短すぎると考えるならより長くとっても構いません。 >>5
[26] ETag: の項も参照。

[30] Last-Modified: ヘッダーキャッシュにおける発見的満期時刻の決定にも用いられます。

DAV:getlastmodified 特性 (WebDAV)

[39] DAV:getlastmodified 特性は、 accept header なしで GET した場合に返されるであろう Last-Modified: ヘッダーの値を表します >>38

[40] 値は HTTPの日時形式です >>38OWSヘッダーに含まれる場合でも、 値には含めるべきではありません >>37

[41] 保護特性であるべきです >>38。 これはキャッシュの適切な動作や Last-Modified の値に依存するクライアントがあるかもしれないからです >>38

[42] COPYMOVE の後の値は、 終点資源の最終修正日時により決まります。 >>38

[43] しかし実装によっては HTTP Last-Modified: の値が変わるべき時であっても、ファイルシステムの日時を使っているため、 変化しないこともあります >>38

[44] Last-Modified は、本体の変更のみを反映するべきであり、 特性のみの変更では変更するべきではありません >>38。 これはクライアントが既存の本体を上書きするべきかどうかの判断に Last-Modified を使うことがあるからです >>38

[45] WebDAV に従う資源GET への応答Last-Modified: ヘッダーを返す場合は、 DAV:getlastmodified 特性を定義しなければなりません >>38

歴史

[2] Last-Modified: 欄は HTTP では実体頭欄に分類されています。 ですから、要求でも応答でも、そのメッセージが (HEAD のように一部省略されている場合も含めて) 実体を含んでいるのなら使えるように思えます。

しかし、 RFC 1945sender とされていたところが、わざわざ RFC 2068 以後は origin server に直されていて、 要求で使えるような気配がまったくありません。

[3] PUTPOST で実体を鯖に送る時には使えないのでしょうか。 (Content-Disposition でも使えというのでしょうか?)

[7] RFC 1945 (HTTP/1.0) 10.10; RFC 2068・2616 (HTTP/1.1) 14.29 Last-Modified

The Last-Modified entity-header field indicates the date and time at which the sender origin server believes the resource variant was last modified. The exact semantics of this field are defined in terms of how the recipient should interpret it: if the recipient has a copy of this resource which is older than the date given by the Last-Modified field, that copy should be considered stale.

Last-Modified 実体頭欄は、 その資源変種が最後に修正された日時と送信者起点鯖が信ずるところのものを示します。この欄の正確な意味は、受信者がこれをどう解釈するべきかによって定義します。受信者がこの資源の複製を持っていて、それが Last-Modified 欄に与えられた日付よりも古ければ、その複製は腐敗していると考えるべきです。

  • Last-Modified = "Last-Modified" ":" HTTP-date

An example of its use is

使用例:

  • Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT

The exact meaning of this header field depends on the implementation of the sender origin server and the nature of the original resource. For files, it may be just the file system last-modified time. For entities with dynamically included parts, it may be the most recent of the set of last-modify times for its component parts. For database gateways, it may be the last-update time stamp of the record. For virtual objects, it may be the last time the internal state changed.

この頭欄の正確な意味は、送信者起点鯖の実装と、 元の資源の性質に依存します。 元がファイルであれば、ファイル・システムの最終修正時刻になるかもしれません。 動的に取り込まれる部分を含む実体では、その構成部分の最終修正時刻のうちで一番新しいものであるかもしれません。 データベース関門では、記録の最終更新時刻印かもしれません。 仮想物体では、内部状態が最後に変更された時刻かもしれません。

An origin server must not MUST NOT send a Last-Modified date which is later than the server's time of message origination. In such cases, where the resource's last modification would indicate some time in the future, the server must MUST replace that date with the message origination date. An origin server should SHOULD obtain the Last-Modified value of the entity as close as possible to the time that it generates the Date value of its response. This allows a recipient to make an accurate assessment of the entity's modification time, especially if the entity changes near the time that the response is generated.

起点鯖は、メッセージを生成する時点の時刻より後の日付を Last-Modified として送ってはなりません。そうなる場合、 つまり資源の最終修正が将来になってしまうような場合は、 メッセージの生成の日付を Last-Modified 時刻としなければなりません起点鯖は、応答の Date 値を生成する時刻とできる限り近い時刻に実体の Last-Modified 値を得るべきです。そうすることで、たとえその実体が応答を生成した時刻の前後に変更されていたとしても、受信者が実体の修正時刻を正確に査定できます。

訳注: Last-Modified 値決定は Date 決定時刻に近づけるよりも、対象となる実体そのものを生成 (取得) する時刻に近づけるべきではないでしょうか。 (もちろん、 実体生成はできる限り Date 決定に近づけるべきですが、 現実には必ずしもそうできる場合ばかりではないでしょう。)

HTTP/1.1 servers SHOULD send Last-Modified whenever feasible.

HTTP/1.1 鯖は、 Last-Modified を可能であればいつでも送るべきです

訳注: 注記なき修正部は RFC 1945→2068 の差分。

[8] RFC 2326 (RTSP/1.0) 12.24 Last-Modified

The Last-Modified entity-header field indicates the date and time at which the origin server believes the presentation description or media stream was last modified. See [H14.29]. For the methods DESCRIBE or ANNOUNCE, the header field indicates the last modification date and time of the description, for SETUP that of the media stream.

[1] Last-Modified 実体頭欄は、 表現記述または媒体流が最後に修正されたと起点鯖の信ずる日時を示します。 DESCRIBE メソッドANNOUNCE メソッドでは、記述の最終修正日時を表します。 SETUP メソッドでは、媒体流の再修正日時を表します。

[4] HTML5 IRC logs: freenode / #whatwg / 20070626 ( 版) <http://krijnhoetmer.nl/irc-logs/whatwg/20070626#l-151> (名無しさん 2007-06-26 13:17:00 +00:00)

実装

[23] ファイルシステムから静的にデータを供給するでは、 ファイルシステム最終修正日時Last-Modified: に設定するのが普通です。

[24] で動的に生成した内容を返す場合には、生成する内容の種類や情報源により、 また実装に用いられているプログラミング言語フレームワークにもよりますが、 Last-Modified: が指定されていることはそれほど多くはありません。 そのためWebブラウザーのキャッシュが有効に作用するであろう場面でも、 毎回へのアクセスが発生することがよくあります。

[46] ApacheCGIスクリプトか指定した値を再整形して応答として使います。 そのため、CGIスクリプトの中には、曜日を適当に指定するなど、 Apache の再整形を期待して適当な出力をするものもあるようです。

[11]>>5

Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT

関連

[25] DOM では Document オブジェクトlastModified IDL属性があり、 HTTP Last-Modified: ヘッダーの値にアクセスできます。

[51] Dockerfile reference ( 版) <https://docs.docker.com/reference/builder/>

If the remote file being retrieved has an HTTP Last-Modified header, the timestamp from that header will be used to set the mtime on the destination file.

[52] IPPSを使って文書を安全に印刷する <http://support.brother.co.jp/j/s/support/html/hl3040cn_jp/ug/html/nug/7-15.html>

Last-Modified: Mon, 01 Jun 2009 08:28:54 GMT,Wed, 26 Feb 2014 03:02:54 GMT

[53] はてなダイアリーの更新時刻 - World Wide Walker (yoosee著, ) <http://yoosee.net/d/archives/2004/01/21/004.html>

五月雨作者のakr さんの日記 によれば、五月雨は基本的に他のアンテナを信用せず、lirs 等の更新情報を元にもう一度自分でチェックに行くらしい。且つコンテンツを GET で fetch するため、HEAD にのみ last-modified フィールドを返すはてなダイアリー 等の場合、更新時刻を正しく取ることが出来ていないようで、ステータスが [NoLM] になる。はてなダイアリーの 2003-03-24 の記述 を見ると、HEAD だけではなく GET リクエストの場合にも last-modified フィールドを返すようにした、と言っている。だが実際に d.hatena.ne.jp にアクセスしてみてみると、

[54] Are Last Modified Headers Recommended? - Google プロダクト フォーラム () <https://productforums.google.com/forum/#!category-topic/webmasters/crawling-indexing--ranking/6A_ctOfMoZw>

From my experience, Google doesn't keep track the Last-Modified header of the page but keeps track of the last time googleboot visited the page. So Google comes with a if-modified-since header that is not related to a page Last-Modified header.