こんにちは、cloudpack比嘉です。

CloudFront経由でHTTPを閲覧した際にヘッダーがおかしなことになっているので調べた
httpとCDNの仕組み的に当たり前なのでしょうがバッドノウハウ的に・・・

準備するもの:

  • apacheとかnginx、IIS入れたサーバ
  • curlコマンド叩くPC
  • AWSアカウント

expiresの期限を10分に設定

Cloudfrontのキャッシュを確認する

<

ol>
1. まずELB経由でアクセスしてヘッダを確認する

curl --verbose http://ELB-DNS-Name/ 1> /dev/null
〜中略〜
< HTTP/1.1 200 OK
* Server nginx/1.6.2 is not blacklisted
< Server: nginx/1.6.2
< Date: Thu, 16 Oct 2014 08:45:35 GMT
< Content-Type: text/html
< Content-Length: 13
< Last-Modified: Thu, 09 Oct 2014 04:58:30 GMT
< Connection: keep-alive
< ETag: "543615f6-d"
< Expires: Thu, 16 Oct 2014 09:45:35 GMT
< Cache-Control: max-age=3600
< Accept-Ranges: bytes

2.Cloudfrontを通してヘッダを取得する

curl --verbose http://CLOUDFRONT-DNS-NAME/ 1> /dev/null
〜中略〜
< HTTP/1.1 200 OK
< Content-Type: text/html; charset=UTF-8
< Content-Length: 61
< Connection: keep-alive
< Accept-Ranges: bytes
< Cache-Control: max-age=600
< Date: Thu, 16 Oct 2014 10:09:09 GMT
< ETag: "4200-3d-505876e003528"
< Expires: Thu, 16 Oct 2014 10:19:09 GMT
< Last-Modified: Thu, 16 Oct 2014 10:08:27 GMT
* Server Apache is not blacklisted
< Server: Apache
< X-Cache: Miss from cloudfront

初回アクセスだったのでCloudfront上にキャッシュが存在していない

DateとExpireがアクセスしたタイミングになっていることを確認

< Date: Thu, 16 Oct 2014 10:09:09 GMT
< Expires: Thu, 16 Oct 2014 10:19:09 GMT
< X-Cache: Miss from cloudfront

3.Cloudfrontを通して1~2分後に再度実行する

< HTTP/1.1 200 OK
< Content-Type: text/html; charset=UTF-8
< Content-Length: 61
< Connection: keep-alive
< Accept-Ranges: bytes
< Cache-Control: max-age=600
< Date: Thu, 16 Oct 2014 10:09:09 GMT
< ETag: "4200-3d-505876e003528"
< Expires: Thu, 16 Oct 2014 10:19:09 GMT
< Last-Modified: Thu, 16 Oct 2014 10:08:27 GMT
* Server Apache is not blacklisted
< Server: Apache
< Age: 68
< X-Cache: Hit from cloudfront

Cloudfrontにキャッシュされたためキャッシュがヒットする

< Date: Thu, 16 Oct 2014 10:09:09 GMT
< Expires: Thu, 16 Oct 2014 10:19:09 GMT
< X-Cache: Hit from cloudfront

4.更に30分後に再度実行

< HTTP/1.1 200 OK
< Content-Type: text/html; charset=UTF-8
< Content-Length: 61
< Connection: keep-alive
< Accept-Ranges: bytes
< Cache-Control: max-age=600
< Date: Thu, 16 Oct 2014 10:09:09 GMT
< ETag: "4200-3d-505876e003528"
< Expires: Thu, 16 Oct 2014 10:19:09 GMT
< Last-Modified: Thu, 16 Oct 2014 10:08:27 GMT
* Server Apache is not blacklisted
< Server: Apache
< X-Cache: RefreshHit from cloudfront

一度キャッシュが切れているがコンテンツに更新が無いためキャッシュを再利用している

Expiresで期限が切れているはずだが変化が無い、ヘッダごとまとめてキャッシュしてるっぽい

< Date: Thu, 16 Oct 2014 10:09:09 GMT
< Expires: Thu, 16 Oct 2014 10:19:09 GMT
< X-Cache: RefreshHit from cloudfront

5.更に5分後に実行

< HTTP/1.1 200 OK
< Content-Type: text/html; charset=UTF-8
< Content-Length: 61
< Connection: keep-alive
< Accept-Ranges: bytes
< Cache-Control: max-age=600
< Date: Thu, 16 Oct 2014 10:09:09 GMT
< ETag: "4200-3d-505876e003528"
< Expires: Thu, 16 Oct 2014 10:19:09 GMT
< Last-Modified: Thu, 16 Oct 2014 10:08:27 GMT
* Server Apache is not blacklisted
< Server: Apache
< Age: 310
< X-Cache: Hit from cloudfront

前回のRefreshHitで使っているキャッシュがそのまま使わてるのでDateとかExpiresとか色々と変になっている

ヘッダを追加してCloudfrontのキャッシュをみる

httpd.confに追加

Header add TestHeader "Sample 1"

1.ヘッダを追加したのでELB経由で確認する

< HTTP/1.1 200 OK
< Accept-Ranges: bytes
< Cache-Control: max-age=600
< Content-Type: text/html; charset=UTF-8
< Date: Thu, 16 Oct 2014 10:55:40 GMT
< ETag: "4200-3d-505876e003528"
< Expires: Thu, 16 Oct 2014 11:05:40 GMT
< Last-Modified: Thu, 16 Oct 2014 10:08:27 GMT
* Server Apache is not blacklisted
< Server: Apache
< TestHeader: Sample 1
< Content-Length: 61
< Connection: keep-alive

TestHeaderを確認

< TestHeader: Sample 1

2.Cloudfront経由で確認する

< HTTP/1.1 200 OK
< Content-Type: text/html; charset=UTF-8
< Content-Length: 61
< Connection: keep-alive
< Accept-Ranges: bytes
< Cache-Control: max-age=600
< Date: Thu, 16 Oct 2014 10:09:09 GMT
< ETag: "4200-3d-505876e003528"
< Expires: Thu, 16 Oct 2014 10:19:09 GMT
< Last-Modified: Thu, 16 Oct 2014 10:08:27 GMT
* Server Apache is not blacklisted
< Server: Apache
< X-Cache: RefreshHit from cloudfront

変更とかしていて10分以上経過していたのでRefreshHitになった(更新の確認は行なっていることになる)

< X-Cache: RefreshHit from cloudfront

また、ヘッダに先ほど追加したはずのTestHeaderが存在しないのでヘッダの変更はCloudfrontでは見ていないことになる

で、どうやったらキャッシュにヘッダを反映させるかとなります。

手段が幾つかあると思います。

  1. CloudfrontでInvalidationを実行する
  2. コンテンツを丸ごと更新する
  3. クエリ文字列渡して新たなキャッシュを作る

普通であれば1になると思いますが、Invalidationが実行できないパターンがあるのでそういった場合はCloudfront自体を作りなおすとかもあるのかもしれません。

自分の試した例ではパスに ~ を含むものが該当していました。 AWSの準拠するRFCがパスに~を含むのはダメっぽいです。(キャッシュはされるんですケドね…)

元記事はこちらです。
Cloudfrontでヘッダー情報が更新されないとかその手のもの