フィンローダのあっぱれご意見番

第71回:URL

初出: C MAGAZINE 1998年03月号
Updated: 1998-04-21

[一覧] [ホームページ]


 お手元に何かインターネット関連の雑誌があれば、広告のページのURLを見て欲しい。URLの最後に「/」が付いていないものがあるはずだ。実は私のページを最初に紹介した時も「/」が付いていなかったかもしれない。無知のなせる技なのだが、実は「/」が付いていないというのはまずいことがある。

 URLとはUniform Resource Locatorsの頭文字を取った表現で、RFC1738で仕様が決められている。これによれば、URLはfig.1のような構造になっている。

---- fig.1 (URL) ----
       <scheme>:<scheme-specific-part>

 <scheme>の所には、プロトコルの類を判別するための手がかりとして、お馴染みのhttpとかftpという文字が入る。後半部分が問題だ。

---- fig.2 (scheme-specific-part) ----
        //<user>:<password>@<host>:<port>/<url-path>

 <user>、<password>はオプションなので、付けなくてもよい。<port>も同様である。例えば「http://www.niftyserve.or.jp/」のようなURLだと、<url-path>の所も省略されている。Web serverは、一部の情報を省略したリクエストが来た時にはデフォルトの値を使うので、自動的にトップページの情報が得られるのだ。

 「/」が付いていないとまずいのはなぜか? 何度か見かけた説明は次のようなものだった。URLがディレクトリの時には「/」を最後に付けないとトラフィックが増加する。だから「/」は付けた方がよい。ところで、NIFTY SERVEのページの中にhttp://www.niftyserve.or.jp という表記があったので、単純にこれは間違いだと思って、そのことを個人の真の裏ページに書いたのである。「真の裏ページ」って何かというと、個人ホームページの他に裏ページと自称しているページが既にあったのだが、NIFTY SERVEのメンバーズホームページサービスが始まった時に、もう一つ裏ページを作って、それを「真の裏ページ」と自称したのである。実はアスキーネットにも同様のページを作るつもりだったが、作る前にアスキーネットがなくなってしまったという歴史がある。

---- fig.3 (HTTP URL) ----
      http://<host>:<port>/<path>?<searchpart>

 HTTP protocolを使う時のURLはfig.3の通りである。HTTPってhyper text transfer protocolだから、HTTP protocolというのはhyper text transfer protocol protocol? でもRFCにそう書いてあるのだ。それはさておき、RFCには"If neither <path> nor <searchpart> is present, the "/" may also be omitted."と書かれている。ということは、<path>も<searchpart>もなければ、「/」を書かなくてもいいのだ。ということは私のアドバイスは大嘘だったということになる。これは結構ヤバい話である。

 もっとも、この通りだと「/」を付けなくてもいけないのは、<path>が空の時である。つまり、http://www.st.rim.or.jp/~phinloda/ というのは<path>の個所がディレクトリだという意味にするために最後の「/」が必要なのだろう。

 言訳にもならないが、NetscapeでURLを「http://www.niftyserve.or.jp」と入力してアクセスしてみて欲しい。URLのテキストボックスの表示はいつの間にか「http://www.niftyserve.or.jp/」になっているはずだ。これはどのような仕組みなのだろうか? 前述のphinlodaの時には次のような仕組みだと言われている。Webサーバは「http://www.st.rim.or.jp/~phinloda」というリクエストを受けて、デフォルトのディレクトリ上に「~phinloda」というファイルを探す。のか? 「~」というのはかなり特殊な意味を持っているから、どうも違うような気もする。とりあえずそうだとして(いい加減で済みません)、そのようなファイルはないから、サーバは「そんなのはないぞ、でも ~phinloda というディレクトリがあるからそれじゃないのか?」という応答を返す。ブラウザはそれを受けて「おお、それだそれ」という応答を返す。サーバはようやく目的のデータを送信する。

 こういう仕組みだとトラフィックが増加するというのも理解できる。


 結局、かなり大きな墓穴を掘っているわけだが、私のページを見ている人がいるというのが結構驚きでもある。とにかく裏ページというのはアングラだからこそ裏ページなのだ。本来の裏ページは年間ヒットが100前後という感じなのだ。

 FPROGの会議室にもURLはたくさん書かれている。NIFTY SERVEにはURLを書くことを禁止しているフォーラムもある。ところがFPROGは全然禁止していないし、逆に推奨しているのではないかと思われる程だ。自社のURLを書いても全然問題ないぞという感じである。逆に、URLを禁止しなければならないとすれば、ソフトやハードの製品名も全部禁止というのが面白そうだ。何の話か分らなくなるかもしれないが、そこはそれ、裏ページで暴露してしまうとか…。

 NIFTY INTERWAYという経路からフォーラムをアクセスすると、URLはそのままリンクとして表示される。便利だ。しかし、別の問題が発生している。世の中にはモラルを勝手に作る人もいる。「このページへのリンクは禁止します」と書いたページを見たことがあるだろうか。そんなものをインターネットに置くなと言いたいものだが、まあわざわざ喧嘩することもないからリンクしないで単にURLだけ紹介して書いておくのだが:-)、これをNIFTY INTERWAYから見ると勝手にリンクになってしまうのだ。この場合、もし「リンクするなと言ったのに勝手にリンクして迷惑だから損害賠償しろ」と言われたりしたら、一体誰がリンクしたことになるのだろうか? 私はリンクなどしていないのだから、訴えるのならINTERWAYを訴えてもらわないと困るのですが。

 電子会議室にURLが書かれていると、テキストからURLを抽出してリンクページを作りたくなる。さて、URLって一体どうやって検出すればよいかだが、perlを使ってパターンマッチングすると、fig.4のような感じでだいたいうまく行く。特殊文字をかなり限定しており、これ以外の文字もURLに使えるかもしれないのだが、殆ど誤差の範囲内と思う。ベタのテキストからURLだけ抜き出す処理の方を重視しているのだ。文章中に現れる場合は、URLの前後にどんな文字が来るか分らないのである。

---- fig.4 (http URLの抽出) ----
    /^(.*)(http:\/\/[0-9A-Za-z\/\-~.,?=_:]*)(.*)$/;


 Webで面白いページが見つかったらその場で読んでもいいが、接続したままではもったいないし、後で読めるとも限らない。とりあえず手元のpcに保存したくなる。保存したファイルが山のように出来ると、そのディレクトリをNetscapeで直接指定しても、ファイル名が適当すぎて、もはやどれが何だか分らない。

 そこでセーブしたHTMLファイルをリンクとして集めたページが欲しくなる。具体的には、次のような処理でリンクページを作るのである。

1) ディレクトリ下にあるHTMLファイルを検査する。
2) <TITLE>タグで指定された内容を使ってリンクを張る。

 例えば、phinloda.htm というファイルの中に、

<title>Phinloda のページ</title>

 というタグがあったら、リンクページには、

<a href="file:///C|/html/phinloda.htm">Phinloda のページ</a>

 という内容を追加するのだ。こういうのを集めたlinks.htmというファイルを作ってブックマークに登録しておくと、後で見る時に便利である。

 ところが、二つの大問題が発生した。まず、タイトルが漢字の場合、文字コードがいろいろあるのだ。Windowsだと、SJISで書かれていると最も問題ないが、JISやEUCで書かれたタイトルも混在した場合、全部同時に表示するという機能はない。別にWindowsでなくてもなさそうだが。ということは、links.htmを作る処理で漢字コードの変換をする必要がある。

 もう一つは、perlの実行中にスタックが不足するエラーが発生したという問題だ。原因に気付かず悩んだのだか、結論から言うと、一行がとてつもなく長いページが処理できなかったのである。このページは改行にCRだけを使っていたのである。LFを改行だと思えば、1行数十KBのテキストである。perlが1行ずつ処理しようとするので、スタックが足りなくなってしまったらしい。

 ということは、CRをCR+LFに置き換えてからperlで処理すればいいのだが、これをperlで一発で処理しようとすると思った通りになかなか動いてくれない。こうなるとCでやってしまえということで、3分で書けるプログラムがList 1である。基本的にはgetcharで1文字読んでputcharで書いてしまえばよいのだが、バイナリモードでファイルをオープンするという面倒なことをしているのでちょっと長いが、それでも割と杜撰である。にもかかわらず、それなりに役にたつ。

---- List 1 ----
#include <stdio.h>

int main(int argc, char *argv[]) {
    FILE *fp;
    int c;

    if (argc < 2)
        return 0;
    fp = fopen(argv[1], "rb");
    if (fp == NULL)
        return 0;
    while ((c = getc(fp)) != EOF) {
        if (c == 0x0d) {
            putchar('\n');
        } else {
            putchar(c);
        }
    }
    fclose(fp);
    return 0;
}

(フィンローダ ニフティサーブ FPROG SYSOP)


(C) 1998 Phinloda, All rights reserved
無断でこのページへのリンクを貼ることを承諾します。問い合わせは不要です。
内容は予告なく変更することがあります。