レスポンスヘッダーのExpires: -1って何?

http://www.amazon.co.jp のレスポンスヘッダーを眺めていると Expires: -1 という不思議な Expire Date が設定されていた。
意味を調べてみた。

Expires レスポンスヘッダー

Expires はキャッシュの期限切れ日時を指定

Expires ヘッダーはコンテンツキャッシュの期限をコントロールし、 HTTP 1.0 から存在している。

RFC 2616 “Hypertext Transfer Protocol — HTTP/1.1” では次のように書かれている

The Expires entity-header field gives the date/time after which the response is considered stale.
http://tools.ietf.org/html/rfc2616#section-14.21

expiration time は HTTP-Date 形式(rfc1123-date | rfc850-date | asctime-date)でかく。

例) Expires: Thu, 01 Dec 1994 16:00:00 GMT

不正な日時

問題は、なんで日時のフィールドに “-1” なんていう数字が設定されているのか?

HTTP/1.1 clients and caches MUST treat other invalid date formats, especially including the value “0”, as in the past (i.e., “already expired”).
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

ということで、Expires に HTTP-Date 以外の形式が設定されると、”already expired” とみなされてキャッシュされない。
「過去」を動的に計算するのはかったるいので、シンプルに「-1」決め打ちにしているのだろう。

なお、未来の日付については “HTTP/1.1 servers SHOULD NOT send Expires dates more than one year in the future.” というように制限されているが、過去の日付については、そのような記述がないからなのか、多様な過去の日付が使われている。

Expires と Cache-Control の違い

HTTP/1.1 ではキャッシュをより細かく制御するために Cache-Control ヘッダーが追加され、max-age でキャッシュ期間を設定できる。
例えば Cache-Control: max-age=300 とすると、クライアントに 300秒はキャッシュするように促す。
max-age と expires の両方が設定されていた場合 max-age を優先する。

If a response includes both an Expires header and a max-age directive, the max-age directive overrides the Expires header, even if the Expires header is more restrictive.
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

IETF Httpbis ワーキンググループの一人で、”Caching Tutorial” などでも有名な Mark Nottingham は

  • ライブラリーを使って expires と Cache-Control:max-age の両方を設定する(Apache の mod_expires、 nginx の ngx_http_headers_module など)
  • Cache-Control: max-age だけを設定する

のいずれかを推奨している

実際の例

ここからは、実際の Web サーバがどのような Expires/Cache-Control を返しているか確認。

# amazon.co.jp
$ HEAD http://www.amazon.co.jp
200 OK
Cache-Control: no-cache
Connection: Keep-Alive
Date: Sat, 01 Feb 2014 04:32:47 GMT
Pragma: no-cache
Server: Server
Vary: Accept-Encoding,User-Agent
Content-Type: text/html; charset=Shift_JIS
Expires: -1
Client-Date: Sat, 01 Feb 2014 04:38:36 GMT
Client-Peer: 54.240.250.0:80
Client-Response-Num: 1
Keep-Alive: timeout=2, max=6
Set-Cookie: skin=noskin; path=/; domain=.amazon.co.jp
X-Amz-Id-1: 1G198XTD4DPPTNQP21KE
X-Amz-Id-2: cHJjNQk6G7uTB7JbLr83QfJ9XTssZwUAnkzLTWxuuGYuiE3MdXXS1SuHl9dVeC85

Cache-Content: no-cache
Expires: -1

# reddit
$ HEAD  http://www.reddit.com/r/gaming/comments/1wog7g/wtf_fifa/
200 OK
Cache-Control: private, must-revalidate, max-age=0
Connection: close
Date: Sat, 01 Feb 2014 04:32:30 GMT
Server: '; DROP TABLE servertypes; --
Vary: accept-encoding
Content-Type: text/html; charset=UTF-8
Last-Modified: Sat, 01 Feb 2014 04:30:56 GMT
Client-Date: Sat, 01 Feb 2014 04:38:19 GMT
Client-Peer: 125.56.218.96:80
Client-Response-Num: 1
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Xss-Protection: 1; mode=block

Cache-Control: max-age=0
Expires: blank

$ HEAD 'http://www.youtube.com/watch?v=uE7qVAtNwQk'
200 OK
Cache-Control: no-cache
Connection: close
Date: Sat, 01 Feb 2014 04:32:10 GMT
Server: gwiseguy/2.0
Content-Type: text/html; charset=utf-8
Expires: Tue, 27 Apr 1971 19:44:06 EST
Alternate-Protocol: 80:quic
Client-Date: Sat, 01 Feb 2014 04:38:00 GMT
Client-Peer: 74.125.235.160:80
Client-Response-Num: 1
P3P: CP="This is not a P3P policy! See http://support.google.com/accounts/bin/answer.py?answer=151657&hl=ja-JP for more info."
Set-Cookie: YSC=hEFCdovBRI0; path=/; domain=.youtube.com; httponly
Set-Cookie: PREF=f1=50000000; path=/; domain=.youtube.com; expires=Thu, 02-Oct-2014 16:25:10 GMT
Set-Cookie: VISITOR_INFO1_LIVE=DnbZPuvLZ5I; path=/; domain=.youtube.com; expires=Thu, 02-Oct-2014 16:25:10 GMT
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block; report=https://www.google.com/appserve/security-bugs/log/youtube

Cache-Control: no-cache
Expires: Tue, 27 Apr 1971 19:44:06 EST

$ HEAD http://stackoverflow.com/questions/18947314/how-to-add-a-linked-source-folder-in-android-studio
200 OK
Cache-Control: public, max-age=60
Connection: close
Date: Sat, 01 Feb 2014 04:33:35 GMT
Vary: *
Content-Length: 63568
Content-Type: text/html; charset=utf-8
Expires: Sat, 01 Feb 2014 04:34:36 GMT
Last-Modified: Sat, 01 Feb 2014 04:33:36 GMT
Client-Date: Sat, 01 Feb 2014 04:39:26 GMT
Client-Peer: 198.252.206.16:80
Client-Response-Num: 1
X-Frame-Options: SAMEORIGIN

Cache-Control: max-age=60
Expires: Sat, 01 Feb 2014 04:34:36 GMT

$ HEAD http://エロサイトコンテンツ
200 OK
Cache-Control: public, s-maxage=1260
Connection: close
Date: Sat, 01 Feb 2014 04:31:50 GMT
Via: 1.1 varnish
Age: 0
Server: nginx
Content-Type: text/html; charset=UTF-8
Client-Date: Sat, 01 Feb 2014 04:37:40 GMT
Client-Peer: 31.192.116.24:80
Client-Response-Num: 1
Set-Cookie: sid=4187441776523501568; path=/; expires=Tue, 31-Dec-2030 12:00:00 GMT; domain=.エロドメイン.com
Set-Cookie: is_pc=1; path=/; expires=Tue, 31-Dec-2030 12:00:00 GMT; domain=.エロドメイン.com
Set-Cookie: country=JP; path=/; domain=.エロドメイン.com
X-Varnish: 3954156791

Cache-Control: s-max-age=1260(varnish 向け)
Expires: blank
Varnish あり

$ HEAD http://en.wikipedia.org/wiki/HTTP_2.0
200 OK
Cache-Control: private, s-maxage=0, max-age=0, must-revalidate
Connection: close
Date: Sat, 01 Feb 2014 04:33:16 GMT
Via: 1.1 varnish, 1.1 varnish
Age: 5700
Server: Apache
Vary: Accept-Encoding,Cookie
Content-Language: en
Content-Type: text/html; charset=UTF-8
Last-Modified: Mon, 06 Jan 2014 09:29:06 GMT
Client-Date: Sat, 01 Feb 2014 04:39:06 GMT
Client-Peer: 208.80.154.224:80
Client-Response-Num: 1
X-Cache: cp1067 hit (5), cp1054 frontend hit (1)
X-Content-Type-Options: nosniff
X-Powered-By: PHP/5.3.10-1ubuntu3.9+wmf1
X-Varnish: 2829631474 2827122309, 1251628819 1244997693
X-Vary-Options: Accept-Encoding;list-contains=gzip,Cookie;string-contains=enwikiToken;string-contains=enwikiLoggedOut;string-contains=forceHTTPS;string-contains=enwikiSession;string-contains=centralauth_Token;string-contains=centralauth_Session;string-contains=centralauth_LoggedOut;string-contains=mf_useformat;string-contains=stopMobileRedirect

Cache-Control: max-age=0, s-maxage=0(Varnish 向け)
Expires: blank
Varnish あり

$ HEAD http://www.1101.com/suimin/samma/index.html
200 OK
Connection: close
Date: Sat, 01 Feb 2014 04:35:02 GMT
Via: 1.1 varnish
Age: 680137
ETag: "11f057d-b69-4480cd52ac500"
Server: Apache
Content-Type: text/html
Last-Modified: Mon, 10 Mar 2008 03:31:00 GMT
Client-Date: Sat, 01 Feb 2014 04:40:51 GMT
Client-Peer: 116.214.86.27:80
Client-Response-Num: 1
X-Varnish: 2679230077 2574494562

Cache-Control: max-age=0
Expires: blank
Varnish あり

$ HEAD http://cookpad.com/pr/contest/index/495
200 OK
Cache-Control: max-age=0, private, must-revalidate
Connection: Close
Date: Sat, 01 Feb 2014 04:33:59 GMT
ETag: "84f438827d94afb908434e1a21064610"
Server: nginx
Vary: User-Agent
Content-Type: text/html; charset=utf-8
Client-Date: Sat, 01 Feb 2014 04:39:49 GMT
Client-Peer: 54.249.90.123:80
Client-Response-Num: 1
Set-Cookie: cpb=00ncva0n099ac3e2370668444ea0a1209980bf9ecc7cb0036f; path=/; expires=Tue, 19-Jan-2038 03:14:07 GMT
Set-Cookie: v=315-4521644-9159558; path=/; expires=Tue, 19-Jan-2038 03:14:07 GMT
Set-Cookie: FVD=%7Bts+%272014-02-01+13%3A33%3A59%27%7D; path=/; expires=Mon, 03-Mar-2014 04:33:59 GMT
Set-Cookie: f_unique_id=15632df6-4323-464f-81a2-b1889828c59c; path=/; expires=Wed, 01-Feb-2034 04:33:59 GMT
Set-Cookie: cids=495; path=/
Set-Cookie: user_type=0; path=/; expires=Mon, 03-Mar-2014 04:33:59 GMT
Set-Cookie: has_kitchen=0; path=/; expires=Mon, 03-Mar-2014 04:33:59 GMT
Set-Cookie: trial_type=0; path=/; expires=Mon, 03-Mar-2014 04:33:59 GMT
Set-Cookie: _myapp_session=BAh7B0kiD3Nlc3Npb25faWQGOgZFVEkiJTQxMzViNmY5NmIzYTVkNGM2MWM5ZTkwMjhhNzk2OTVhBjsAVEkiEF9jc3JmX3Rva2VuBjsARkkiMW9IRFc3THUyUkNnbWRLdXNGb1MrSW9Yd2djSzN6YnU0azcrcjhSbytxOUk9BjsARg%3D%3D--4ca3911027db73825d5fd98b353ff2cb11578e16; path=/; HttpOnly
Set-Cookie: withoutvns=; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT
Status: 200 OK
X-ASC: 159
X-ASN: 159
X-Chst: 32a6df64098aa9ada256c6e881941985
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Request-Id: d87e903120c048d56784636a9c608a45
X-Runtime: 0.287018
X-XSS-Protection: 1; mode=block

Cache-Control: max-age=0
Expires: blank

$ HEAD http://www.w3.org/Protocols/rfc2616/rfc2616.html
200 OK
Cache-Control: max-age=21600
Connection: close
Date: Sat, 01 Feb 2014 04:34:20 GMT
Accept-Ranges: bytes
ETag: "805b-3e3073913b100"
Server: Apache/2
Content-Length: 32859
Content-Type: text/html; charset=iso-8859-1
Expires: Sat, 01 Feb 2014 10:34:20 GMT
Last-Modified: Wed, 01 Sep 2004 13:24:52 GMT
Client-Date: Sat, 01 Feb 2014 04:40:10 GMT
Client-Peer: 128.30.52.37:80
Client-Response-Num: 1
P3P: policyref="http://www.w3.org/2001/05/P3P/p3p.xml"

Cache-Control: max-age=21600
Expires: Sat, 01 Feb 2014 10:34:20 GMT

$ HEAD  http://tokyo.craigslist.jp/act/4313870292.html
200 OK
Cache-Control: max-age=300, public
Connection: close
Date: Sat, 01 Feb 2014 03:49:13 GMT
Server: Apache
Vary: Accept-Encoding
Content-Type: text/html; charset=iso-8859-1
Expires: Sat, 01 Feb 2014 03:54:13 GMT
Last-Modified: Sat, 01 Feb 2014 03:49:13 GMT
Client-Date: Sat, 01 Feb 2014 04:49:50 GMT
Client-Peer: 208.82.238.226:80
Client-Response-Num: 1
Client-Transfer-Encoding: chunked
X-Frame-Options: SAMEORIGIN
X-MCP-Cache-Control: max-age=2592000, public

Cache-Control: max-age=300
Expires: Sat, 01 Feb 2014 03:54:13 GMT

$ HEAD http://nginx.org/en/docs/http/ngx_http_headers_module.html
200 OK
Connection: close
Date: Sat, 01 Feb 2014 04:34:46 GMT
Accept-Ranges: bytes
ETag: "528dfca7-1f0c"
Server: nginx/1.5.7
Content-Length: 7948
Content-Type: text/html; charset=utf-8
Last-Modified: Thu, 21 Nov 2013 12:29:27 GMT
Client-Date: Sat, 01 Feb 2014 04:40:35 GMT
Client-Peer: 206.251.255.63:80
Client-Response-Num: 1

Cache-Control: blank
Expires: blank

References

Advertisements
Tagged with: , , ,
Posted in web
One comment on “レスポンスヘッダーのExpires: -1って何?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Archives
  • RT @__apf__: How to write a research paper: a guide for software engineers & practitioners. docs.google.com/presentation/d… /cc @inwyrd 4 months ago
  • RT @HayatoChiba: 昔、自然と対話しながら数学に打ち込んだら何かを悟れるのではと思いたち、専門書1つだけ持ってパワースポットで名高い奈良の山奥に1週間籠ったことがある。しかし泊まった民宿にドカベンが全巻揃っていたため、水島新司と対話しただけで1週間過ぎた。 それ… 5 months ago
  • RT @googlecloud: Ever wonder what underwater fiber optic internet cables look like? Look no further than this deep dive w/ @NatAndLo: https… 5 months ago
  • @ijin UTC+01:00 な時間帯で生活しています、、、 10 months ago
  • RT @mattcutts: Google's world-class Site Reliability Engineering team wrote a new book: amazon.com/Site-Reliabili… It's about managing produc… 1 year ago
%d bloggers like this: