桑田といいます。

> るびきちです。
>
> cgi.rbのCGI::TagMaker、CGI::HtmlExtension等を使っている人はいるでしょうか?
> あまり使われていないのであれば、cgi/html.rbとかに分離したほうがいい気がします。
>
> また、CGI::escape系はcgi/escape.rbに分離して、cgi.rbでrequireすれば
> cgi/escape単独で使用する場合はコンパクトになります。どうでしょうか?

参考までに、cgi.rbを書き換えた CGIAlt というのを作ってます。
http://cgialt.rubyforge.org/

cgi.rbを以下のように分解してます。
* cgialt.rb
* cgialt/core.rb
* cgialt/util.rb
* cgialt/cookie.rb
* cgialt/html.rb

また CGI.escapeHTML や CGI.unescape を拡張ライブラリで書き直しています。
http://cgiext.rubyforge.org/

書き直して分かったこと:

(1) CGI.unescape() が遅いせいで、request parameter や cookie の
    デコードが遅い
    → 解決策: CGI.unescape() を拡張ライブラリで書き直す
(2) CGI.escapeHTML() が遅いので、PHPの htmlspecialchars() と比べて不利
    → 解決策: CGI.escapeHTML() を拡張ライブラリで書き直す
(3) CGI::Cookie class が DelegateClass(Array) を使っているせいで、
    require 'cgi' にすごく時間がかかる (ruby の起動より時間がかかる)。
    (時間がかかるのは CGI::HtmlExtention まわりのせいではない)
    → 解決策: DelegateClass(Array) を使わないように書き換える
(4) multipart のときに、データサイズを確認せず受信してるので、
    極めて大きいファイルを送信されるとサーバ資源を食いつぶす
    → 解決策: 受信するデータサイズの上限を設定する
(5) multipart のときに、filename のある・なしに関係なく、値を
    Tempfile や StringIO に格納している。本来なら filename の
    ある値のみ Tempfile を使い、そうでないなら普通に String で
    よいはず
    → 解決策: インターフェースを変えないといけないので、解決は難しい
(6) CGI#initialize() の中で ENV['QUERY_STRING'] や ENV['HTTP_COOKIE'] を
    parse しているので、FastCGI のように ENV を使わない場合、
    cgi.rb を使うのが困難
    (実際、fcgi.rb での cgi.rb 対策は悲惨なコードになっている)
    → 解決策: workaround として、$ENV = ENV をしてから、
       CGI#initialize() では ENV のかわりに $ENV を使うように変更
(7) mod_ruby 対応がやっつけ仕事で効率が悪い
    → 解決策: 最初から mod_ruby 対応を考えて書き直す
(8) テストスクリプトがまったく用意されていない
    → 解決策: 地道にテストスクリプトを書く (CGIAlt には添付済)

(1)と(2)は pure Ruby では解決しにくい問題なので、拡張ライブラリを
使うのがいいと思います。というか、パフォーマンスのために基本的な
関数は拡張ライブラリで提供してほしいところです。

(3)と(4)と(8)は今すぐにでも解決できる問題なので、対応を検討して
いただけるとうれしいです。
# 以前、(8) を提案したときにまったくの無反応だったのですが、
# 誰も興味ないのでしょうか。

書き直して思ったのは、cgi.rbを書き直したところで良くならないと
いうことです。1.9 を見据えて、cgi.rb の代替物を広く公募しては
いかがでしょうか。
PHP を dis ってる場合じゃないです。

--
makoto kuwata