<前の日記(2006年06月24日) 次の日記(2006年07月01日)> 最新 編集

高木浩光@自宅の日記

目次 はじめに 連絡先:blog@takagi-hiromitsu.jp
訪問者数 本日: 1770   昨日: 2980

2006年06月25日

Java用「winnytp://」プロトコルハンドラを作ってみたら簡単にできた

タイミングのよいことに、11日の日記の「Winny可視化のため、WebブラウザにWinnyプロトコルハンドラを」に対して、「高木版Winnyプロトコルハンドラは妙だ」という反応があった。

それを言うなら winnytp://a272e2d2e7a6844d97ab5fd9619be1d6 というURIで、ネットワークのどこかにある a272e2d2e7a6844d97ab5fd9619be1d6 というハッシュのファイルを指すのが自然なんじゃないかと。

高木版Winnyプロトコルハンドラは妙だ, blog.fuktommy.com, 2006年6月25日

べつにそれに限定される理由はない。両方があり得るというだけのことだ。 URL (Uniform Resource Locator) として、場所を指定してリソースを指定する方法「winnytp://HOSTNAME:PORT/[FILE_ID]」もあれば、 URN (Uniform Resource Name) として、場所に依存しない形でリソースを指定する方法「winny:FILE_ID」もあり得るという理解でよい。*1

私は単に、後者の実装には興味がない。

実装の面からいうとWinnyプロトコルには自分の公開ファイルの一覧を出力する機能はなかったと思うんですけど。 Apacheでいえば Options -Indexes と設定しているようなもんでしょ。ということは winnytp://192.168.2.1:7743/foo.jpg はありえても winnytp://192.168.2.1:7743/ はないんじゃないですか。

高木版Winnyプロトコルハンドラは妙だ, blog.fuktommy.com, 2006年6月25日

べつに全ファイルが表示される必要はない。そのサイトから受信したコマンド13から、そのサイトについてのエントリを抽出する実装でよいのであって、「Options -Indexes」されているわけじゃない。

じつは言い出した当初、それができるかどうかいささか不確かに感じていた。そこで、ちょうど昨日から、実際に作って試していたところだった。

Javaのjava.net.URLConnection用のストリームハンドラを軽く書いてみた。使い方は次のような感じになる。Javaで書いたため一般のWebブラウザに組み込むことはできそうにないが(HotJavaにならできるけども)、ここではテキストベースのHTMLブラウザをJavaで書くケースを想定している。(ダウンロード機能はまだ書いていないので「[FILE_ID]」部分は指定しても無視される。)

import java.net.URL;
import java.io.*;
public class Nynx {
    static final String usage = "Usage: java Nynx url";
    public static void main(String[] args) {
        if (args.length != 1) {
            System.err.println(usage);
            System.exit(1);
        }
        String url = args[0];
        URL.setURLStreamHandlerFactory(new WinnytpURLStreamHandlerFactory());  // ハンドラの組み込み
        try {
            java.net.URLConnection uc = new URL(url).openConnection();
            InputStream is = uc.getInputStream();
            BufferedReader buf = new BufferedReader(new InputStreamReader(is));
            while (true) {
                String line = buf.readLine();
                if (line == null) break;
                System.out.println(line);
            }
        } catch (IOException e) {
            System.err.println(e.toString());
        }
    }
}
class WinnytpURLStreamHandlerFactory implements java.net.URLStreamHandlerFactory {
    public java.net.URLStreamHandler createURLStreamHandler(String protocol) {
        if (protocol.equals("winnytp")) {
            return new WinnytpURLStreamHandler();
        } else {
            return null;
        }
    }
}
class WinnytpURLStreamHandler extends java.net.URLStreamHandler {...}
class WinnytpURLConnection extends java.net.URLConnection {...}

実行してみると次のようになる。図1は実装途中の確認テストで実行した際の様子で、受信したコマンド13のエントリを削らずに表示した様子だ。

図1: 送られてきたコマンド13のエントリをHTML化して表示した様子

ここから、HOST_NAME部分がアクセス先サイトと一致するエントリ(図1の矢印部分)だけを残して表示すればよく、実行すると図2のようになった。(リンクのhref属性は、相対URLになるので「winnytp://HOSTNAME:PORT/」部分を省略している。)

図2: winnytp://HOSTNAME:PORT/ 表示の完成形

このとき、こちらからサーバ(Winnyノード)へは何らコマンドもデータも送信していない(Winnyプロトコル冒頭の暗号キーおよびコマンド0〜3も送っていない)。実装の最初のテストでそのことに気づいたのだが、単にこちらから TCP接続しただけで、応答ストリームにコマンド13などを返してくるようだ。受信したデータをWinnyプロトコルにしたがってデコードしただけで、このような表示ができた。

昨日(土曜日)の夕方から書き始めたところ、今日(日曜日)の朝にはこの程度に動くものに仕上がった。このことからしても、今や誰でも、公開されている資料をもとにこうしたプログラムを作成できる状況にあることがわかる。実際、5月15日のCMU日本校のカンファレンスの席でも、会場からの質問で「(情報漏洩対策として)うちでも作っている」という声が出ていた。

補足

Winnyについてこれまでに考えを記した日記:

*1 そのためわざわざ「tp」を付けて区別しておいた。

本日のTrackBacks(全1件) [TrackBack URL: http://takagi-hiromitsu.jp/diary/tb.rb/20060625]
検索

<前の日記(2006年06月24日) 次の日記(2006年07月01日)> 最新 編集

最近のタイトル

2016年06月12日

2016年06月03日

2016年04月23日

2016年04月06日

2016年03月27日

2016年03月14日

2016年03月06日

2016年02月24日

2016年02月20日

2016年02月11日

2016年02月05日

2016年01月31日

2015年12月12日

2015年12月06日

2015年11月23日

2015年11月21日

2015年11月07日

2015年10月20日

2015年07月02日

2015年06月14日

2015年03月15日

2015年03月10日

2015年03月08日

2015年01月05日

2014年12月27日

2014年11月12日

2014年09月07日

2014年07月18日

2014年04月23日

2014年04月22日

2000|01|
2003|05|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|05|06|07|08|09|10|11|12|
2012|02|03|04|05|06|07|08|09|
2013|01|02|03|04|05|06|07|
2014|01|04|07|09|11|12|
2015|01|03|06|07|10|11|12|
2016|01|02|03|04|06|
<前の日記(2006年06月24日) 次の日記(2006年07月01日)> 最新 編集