[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[FDclone-users:00916] Re: URLDRIVE で HTTP を HTTPS にリダイレクトされると変に



 しらいです。

In Message-Id <20100901081609.229bc869.riki1017kazu@gmail.com>
        Rikito INAKAZU <riki1017kazu@gmail.com>さんwrites:
> 稲員です。

> 先日 FDclone-3.00i 上から 'x' で次のコマンドを実行しました。
> 
>   wget http://launchpad.net/bzrtools/stable/2.2.0/+download/bzrtools-2.2.0.tar.gz

 えーと、URLDRIVE=1 の時には、URL 文字列はそれを local にコ
ピーした一時ファイルのパス名として command 引数に渡されるの
で、例えば wget の場合は引数を quote する必要があります。
 「cp http://xxx .」のように記述することで wget と同じこと
が実現出来る訳ですが、今回はそういった辺りは十分承知の上で書
いてらっしゃいますよね?
 上記のように記述された wget が期待通りの挙動を示さないのは
URLDRIVE の仕様ですので、その点まず確認させて下さい。


> ところが network access はしている様子なのに一向に download
> が始まる気配がないので変だと思い packet を覗いてみると、
> 延々と同じ request を送り続けていることが判明。慌てて ^C で
> 止めたら急に download が始まり、それが終了すると今度は何も
> 入力を受け付けなくなってしまい、結局 kill -9 することに。

 今回のバグ報告はこの無限ループを指摘したものだと解釈して話
を進めます。URLDRIVE 機能を用いて上記の URL にアクセスすると、
確かに無限ループに陥っていました。


> その後の調査で、どうやら URLDRIVE=1 の時に http://.. へのア
> クセスが https://.. にリダイレクトされる URL を指定した時に
> おかしくなっている事が分かりました。

 FDclone の URLDRIVE 機能は scheme として ftp と http しか
対応していないので、https に redirect することが出来ません。
SSL 組込むと途端にデカい binary になっちゃいますし。
 こういうケースでは本来エラーで弾かれる必要がある訳ですが、
適切な error message を表示させるのは難しそうですね。現状で
はエラー時は単なる文字列と見なして処理を次に進めちゃうので。

 上の URL のアクセスに失敗している箇所を追ってみると、末尾
の bzrtools-2.2.0.tar.gz に辿り着く前に、その上層 directory
を解析しようとして失敗して文字列として扱ってます。
 なので無限ループは回避出来ても、URL を文字列として引数に渡
しちゃうことになって、wget なり cp なりにそんな引数渡されて
も困ると言われてしまうんですよね。
 あ、wget の場合は文字列として渡されて大丈夫なんですが。

 ちょっとこの辺りの挙動は今後の課題とさせて下さい。そもそも
URLDRIVE も DOSDRIVE も shell の機能としては無理のある仕様で
すもので。


>  	if ((ptr = urlparse(s, NULL, &cp, &type)) < 0) return(-1);
> +	if (type == TYPE_UNKNOWN) {
> +		urlhostlist[uh].prototype = TYPE_UNKNOWN;
> +		return(-1);
> +	}
>  	if (ptr > 0) {
>  		n = urlgethost(cp, &tmp);
>  		Xfree(cp);

 さてこの patch の箇所なんですが、そもそもは urlparse() の
使い方を間違えているのが悪くて、type の値を見ていないからで
はありませんでした。
 urlparse() の仕様としては負数がエラーではなくて 0 がエラー
なんですよ。なので負数が返ってそのまま下に落ちてる時点でまず
くて、type の値が何なのかはこの際関係ありません。

 で、urlparse() が失敗するケースには二通りあって、そもそも
Location 文字列が URL じゃない場合と、今回のような非対応 URL
の場合とですね。
 前者は redirect 先が local だった場合にあり得る話なので、
これはエラーとして弾いてはまずくて、後者だけ弾かないといけま
せん。
 開発途中の source は残ってないのでここからは推測なんですが、
当初は前者のケースの返り値が 0 で後者のケースの返り値が負数
だったんじゃないでしょうかね。なら元のコードで正しい訳で。

 という訳で下記のような patch でどうでしょうね?

---- Cut Here ----
diff -u ../old/FD-3.00i/http.c ./http.c
--- ../old/FD-3.00i/http.c	Sat Jul 24 00:00:00 2010
+++ ./http.c	Sat Sep  4 05:10:44 2010
@@ -347,8 +347,10 @@
 	char *cp;
 	int n, ptr, type;
 
-	if ((ptr = urlparse(s, NULL, &cp, &type)) < 0) return(-1);
-	if (ptr > 0) {
+	if (!(ptr = urlparse(s, NULL, &cp, &type))) {
+		if (urlparse(s, (scheme_t *)nullstr, NULL, NULL)) return(-1);
+	}
+	else {
 		n = urlgethost(cp, &tmp);
 		Xfree(cp);
 		if (n < 0 || !(tmp.host)) return(-1);
---- Cut Here ----

                                               しらい たかし