wgetの-npオプションの実装

ふとしたことから,友人とある課題に取り組んでいるわけで.


とあるURLにあるhtmlから,その階層以下のファイルのみを対象にしたパターンを考えている.

  • 相対URLで`..'が出てくるのと,
  • 外部ドメインのURLが`http://......'ではじまるだろうということで
file="[^h.]*/.*\.($ext)"

という感じの正規表現を考えた.$extは拡張子.(jpg|png)とかそんなん.
役割を果たすようにスクリプト自体は書けたのだが,
どうも,自分としてはこのパターンがスマートに見えない.


んじゃあ,実装例を見てみようということでwgetのソースを読み始めてみた.
結論から言ってソース(wget-1.11.4)を見てもよく分からない!


ディレクトリを見ないというオプションである`-np'オプションは
コマンドライン引数はsetvalopt()を使ってopt
main.c: main():

struct cmdline_option *opt;

に入れられる.
URLからダウンロードするところは

status = retrieve_url (*t, &filename, &redirected_URL, NULL, &dt, opt.recursive);

の部分だと思う.
# optを渡していないのが謎なのだが.


そして,
retr.c: retrieve_url():

result = http_loop (u, &mynewloc, &local_file, refurl, dt, proxy_url);

でダウンロードの準備とかログとか.メインループ的な.


http.c: http_loop():

/* Try fetching the document, or at least its head.  */
err = gethttp (u, &hstat, dt, proxy);

んで,結局ここでダウンロードしてるっぽい.
ソケットを開いたりなんやらと,色々をやっている.
この中を見ても,コメントは付いているものの専門的で現段階で理解できず.


npがONになっているときは,opt.recursiveがtrueだから
main.c: main():

status = retrieve_tree(*t);

の方だろうか?
でも,このすぐ下にftpの名前を持つ関数があるのが気になる.
やりたいのはhttpの方なんだけどな.


recur.c: retrieve_tree():

 = get_urls_html (file, url, &meta_disallow_follow);
if (children)
  {

あたりが怪しい.


指定URLから再帰動作させたときに,どういう順序でURLを回るかは
retrieve_tree()のヘッダ部.深さ優先探索
どうやらタグからURLツリーを作っているようだ.


html-url.c: get_urls_html():

 struct map_context ctx;

あやしい.
struct map_contextの定義部を見ると,base URIの設定している?
この関数にはタグを解析する部分が存在する.


ちょっと予想.
aタグ内のhref要素が相対URIだったら絶対URIに変換して,
一番最初(再帰し始め)のURIと比較することで,上位の階層に行ってないことを知る.
こんな感じでnpオプションが実装されていたりしないかなあ.


相対URIから絶対URIの変換を調べてみた*1
http://www.ietf.org/rfc/rfc1808.txt
「4. Resolving Relative URLs」の「Step 6」に手順が書いてあった.


でも結局,これは`..'を使って上のディレクトリ名(RFC内ではという単語)を
削除すると書いてあるな.
そうすると,上位のディレクトリ名には`..'を使う以外にはマッチしないのか?


ってことは,冒頭の正規表現でいいってことになってしまうなあ.
うーん.
スマートじゃないんだよなあ...

参考

6.4 URI

本仕様書では、URIという語を、 [URI]が定義する通りの意味で用いる。 ( [RFC1630]をも参照のこと。)

URIにはURLも含まれるということに注意されたい。([RFC1738]と [RFC1808]が定義する通り。)

相対URIは、基底URIを用いてフルURIへと解決される。 [RFC1808]の3が、この手続きの規範的アルゴリズムを規定している。基底URIについて、より詳しくはリンクの章の 基底URIの項目を参照のこと。

URIは、DTD中ではパラメータ実体%URI;として表現される。

URIは基本的に大文字小文字を区別する。コンピュータ名など、URIあるいはURIの一部分において大文字小文字が区別されない場合があるが、ここの詳細を特定するのは困難である。ユーザは、安全性の面から、URIは常に大文字小文字を区別すると覚えたほうがよい。

URI属性値における非ASCII文字の扱いについては附属書【B】を参照のこと。

http://www.asahi-net.or.jp/~sd5a-ucd/rec-html401j/types.html#h-6.4