障害調査の途中で「このサイトのindex.htmlに、1ヶ月前の時点でCache-Controlヘッダが付いていたか」を確かめる必要が出てきた。現在のレスポンスを見ても過去のことは分からず、Wayback Machineにも該当ページの記録が無かった。最終的に、Common Crawlのアーカイブ(WARC)から当時のHTTPレスポンスヘッダを原文のまま取り出せたので、その手順を残しておく。
Wayback Machineに無いページはCommon Crawlを当たる
過去のWebページというとWayback Machine(web.archive.org)が定番だが、日本の中小規模サイトは記録されていないことが多い。今回もCDX APIで照会したが結果は空だった。
curl -s "http://web.archive.org/cdx/search/cdx?url=example.jp&output=json&limit=10"
# → []
一方Common Crawlは、月1回ペースでWeb全体をクロールしてWARC形式で公開している非営利プロジェクトで、こちらには記録が残っていた。WARCはリクエスト・レスポンスをヘッダごと丸ごと保存する形式なので、「当時どんなヘッダで配信されていたか」がそのまま分かる。これがWayback Machineとの大きな違いで、Wayback Machineの再生ページは配信時にヘッダが書き換わるが、WARCの生データには手が入っていない。
CDX APIでクロール記録を探す
まず、どのクロール(インデックス)があるかを確認する。
curl -s "https://index.commoncrawl.org/collinfo.json"
# CC-MAIN-2026-30, CC-MAIN-2026-25, CC-MAIN-2026-21, ... が返る
インデックス名の数字は「年-週番号」なので、調べたい時期に近いものを選んで、CDX APIでURLを検索する。ワイルドカード指定でドメイン配下をまとめて探せる。
curl -s "https://index.commoncrawl.org/CC-MAIN-2026-25-index?url=example.jp%2F*&output=json&limit=20"
ヒットすると1件1行のJSONが返る(値は例)。
{"urlkey": "jp,example)/", "timestamp": "20260610012345",
"url": "https://example.jp/", "mime": "text/html", "status": "200",
"length": "1400", "offset": "123456789",
"filename": "crawl-data/CC-MAIN-2026-25/segments/1780000000000.00/warc/CC-MAIN-20260610000000-20260610030000-00123.warc.gz"}
重要なのは filename、offset、length の3つ。巨大なWARCファイル(1つ約1GB)の中の、どの位置に目的のレコードがあるかを示している。
WARCレコードをRangeリクエストで切り出す
WARCファイルを丸ごとダウンロードする必要はない。gzipのレコード単位で連結されたファイルなので、HTTPのRangeリクエストで該当部分だけ切り出して、そのままgunzipできる。範囲は offset から offset + length - 1 まで。
# 123456789 + 1400 - 1 = 123458188
curl -s -r 123456789-123458188 "https://data.commoncrawl.org/crawl-data/CC-MAIN-2026-25/segments/1780000000000.00/warc/CC-MAIN-20260610000000-20260610030000-00123.warc.gz" -o record.warc.gz
gunzip -c record.warc.gz | head -40
取り出せたレコードがこれ。クロールされた時点の、レスポンスヘッダの原文が丸ごと残っている。
WARC/1.0
WARC-Type: response
WARC-Date: 2026-06-10T01:23:45Z
WARC-Target-URI: https://example.jp/
HTTP/1.1 200
content-type: text/html
date: Wed, 10 Jun 2026 01:23:45 GMT
last-modified: Tue, 12 May 2026 08:00:00 GMT
vary: Accept-Encoding
X-Crawler-content-encoding: gzip
server: AmazonS3
x-cache: Miss from cloudfront
via: 1.1 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.cloudfront.net (CloudFront)
x-amz-cf-pop: IAD61-P9
<!DOCTYPE html>
...
今回知りたかったのは「当時Cache-Controlが付いていたか」で、答えは「付いていなかった」。ヘッダ一覧に無いこと自体が証拠になった。加えて server: AmazonS3 や via: CloudFront から当時の配信構成、last-modified からファイルの最終更新日(約1ヶ月間更新されていなかったこと)まで読み取れて、調査が一気に進んだ。
読むときの注意点
X-Crawler-content-encoding: gzipはCommon Crawl側が付けた注記で、「元はgzip配信だったが、本文は展開済みで保存してある」という意味。オリジナルのヘッダと混同しないこと- CDXの
lengthは展開後ではなく「WARC内での圧縮済みレコード長」。Range計算にはこちらを使う - 本文(HTML)もレコード内にそのまま入っているので、当時のページ内容の確認にも使える
制約: すべてのURLがあるわけではない
クロールは月1回ペースで、1回のクロールで同一サイトから取得されるのは数ページ〜数十ページ程度。トップページや被リンクの多いページは残りやすいが、深い階層のページやJS・CSS・画像などのアセットはまず記録されていない。今回もトップページのHTMLは取れたが、アセットファイルの記録は無かった。「あれば儲けもの」くらいの期待値で、まずCDX APIを叩いてみるのがよい。