WGET-E.TXT (日本語訳)
[Previous] [Next] [Up] [Home]
--------------------------------------------------

Time-Stamping : タイムスタンプ


インターネットから情報をミラーリングする上で重要な点の 1 つが、ローカルなアーカイブの更新です。
数少ない更新ファイルを置き換えるためだけに繰り返しアーカイブ全体をダウンロードしていては、帯域と経費の無駄使い、および更新にかかる時間の両面から、運用コストが高くなってしまいます。すべてのミラーリング ツールには差分更新オプションが設けられていますが、その理由はここにあります。
このような更新の仕組みから、「新しい」ファイルを探してリモート サーバーがスキャンされることがわかります。古いファイルの代わりに、新しいものだけをダウンロードするのです。

次の 2 つの条件のいずれかに当てはまるとき、そのファイルは新しいと見なされます。

  1. 同名ファイルがローカルに存在しないとき。
  2. 同名ファイルが存在するが、リモート ファイルの更新日時がローカル ファイルよりも新しいとき。

この機能を実装するためには、プログラムはリモートとローカルの両方のファイルの最終更新日時を知らなくてはなりません。このような情報を「タイムスタンプ」と呼びます。

GNU Wget のタイムスタンプを有効にするには、--timestamping (-N) オプション、または .wgetrc の timestamping = on ディレクティブを使用します。このオプションを指定すると、Wget は、ダウンロードされる各ファイルについて、同名のローカル ファイルが存在するかどうかをチェックします。同名ファイルが存在し、かつリモート ファイルのほうが古ければ、そのファイルはダウンロードされません。

ローカル ファイルが存在しない、またはファイルサイズが一致しない場合、Wget はタイムスタンプに関わらずリモート ファイルをダウンロードします。


タイムスタンプの使い方

タイムスタンプの使い方は簡単です。 Wget に、更新日時を記憶してファイルをダウンロードしたいと伝えればいいのです。

wget -S http://www.gnu.ai.mit.edu/

ls -l を実行すると、サーバーから返ってきたローカル ファイルのタイムスタンプが Last-Modified ヘッダの記述と一致していることがわかります。ご覧の通り、-N を指定しなくても、タイムスタンプ情報はローカルに保存されます。

数日後、リモート ファイルが変更されたかどうかを調べ、変更されていたらダウンロードしたくなるでしょう。

wget -N http://www.gnu.ai.mit.edu/

Wget はサーバーに最終更新日時を問い合せます。ローカル ファイルが新しければ、リモート ファイルを再取得することはありません。しかし、リモート ファイルのほうが新しければ、Wget は通常通りの取得を行います。

FTP についても同じです。たとえば、

wget ftp://ftp.ifi.uio.no/pub/emacs/gnus/*

ls を使えば、リモート サーバー上の状態にしたがってタイムスタンプがセットされたことが確認できるでしょう。 -N を指定してコマンドを再実行すると、Wget は更新されたファイル *だけ* を再取得します。

Wget は、HTTP と FTP のいずれから取得する場合でも、時間情報が得られれば、(-N の指定の有無に関わらず) 適切にローカル ファイルのタイムスタンプを設定します。時間情報とはすなわち、FTP ではディレクトリ リスト、HTTP では Last-Modified ヘッダです。

もし GNU アーカイブを毎週ミラーリングしたいのであれば、次のコマンドを毎週実行すればいいでしょう。

wget --timestamping -r ftp://prep.ai.mit.edu/pub/gnu/

HTTP タイムスタンプ

HTTP のタイムスタンプは Last-Modified ヘッダをチェックすることで実現されています。 HTTP 経由でファイル foo.html を取得するとき、Wget はローカルに foo.html が存在するかどうかを調べます。存在しなければ、無条件で foo.html を取得します。

ローカルにファイルが存在しなければ、Wget はまずローカルのタイムスタンプ (ls -l がチェックするのと同様の方法) を調べ、次にリモート サーバーに HEAD リクエストを送信し、リモート ファイルの情報を要求します。

Wget は、リモートとローカルのどちらのファイルの変更日時がより最近であるかを知るために、Last-Modified ヘッダを調査します。リモート ファイルのほうが新しければ、そのファイルがダウンロードされます。古ければ処理を中断します (*1)。

理論上は、HTTP タイムスタンプの実装は If-Modified-Since リクエストを使って行うべきでしょう。

-- 脚注 --
(*1) 追加チェックとして、Wget は Content-Length ヘッダも調べ、サイズを比較します。これが一致しなければ、タイムスタンプがどうなっていようと、リモート ファイルをダウンロードします。


FTP タイムスタンプ

理論的には、FTP タイムスタンプは HTTP とほとんど同様に機能しますが、FTP にはヘッダ情報が含まれません。したがって、タイムスタンプはディレクトリ リストから取得しなくてはなりません。

対象となる各ディレクトリ ファイルに対し、Wget は LIST コマンドを使用してリストを取得します。そして、出力結果を Unix の ls -l のものと見なしてリストの解析を試み、タイムスタンプを抽出します。それ以外の処理は HTTP の場合とまったく同じです。

各ディレクトリ リストが Unix スタイルであると仮定するのは無理が大きいと思われるかもしれませんが、実際にはそんなことはありません。 Unix 互換のリスト形式はほとんどの (すべての?) クライアントが理解できるため、多くの non-Unix FTP サーバーが採用しているのです。断っておきますと、RFC959 には、タイムスタンプはおろか、ファイルリストを取得する標準的な方法は定義されていません。将来の標準化でこの点が定義されることを願うばかりです。

そのほかに、標準的ではありませんが、いくつかの FTP サーバー (有名な wu-ftpd が含まれます) でサポートされている MDTM コマンドを使用する方法が考えられます。このコマンドは、特定のファイルの正確な時間情報を返します。将来的に Wget は、このコマンドをサポートするかもしれません。

 

----------------------------------------
れいず・ぶーす > 翻訳っぽい話 > ドキュメント > WGET-E.TXT
[Previous] [Next] [Up] [Home]