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