Perl FastCGIと日本語の"Wide character in FCGI::Stream::PRINT"問題など
某所でFreeBSD 8.1-RELEASEを突っ込んで、 テスト版のApache+Perl FastCGIのサーバをこさえたんだけど、 いざ日本語のUTF-8の表示をしようとすると、 "Wide character in FCGI::Stream::PRINT at *.fcgi line x"てな感じのエラーが出て使えないのでありますよ。
ちなみにエラーはデフォのErrorLogであるhttpd-error.logもしくはVirtualHostのErrorLogに吐かれます。 もちろんマルチバイト文字を表示しない限りは問題なかったりするのですが。 しかもそのくせ、FCGIのスクリプトをシェルから直接実行してみると、 Wide Characterのエラーも出ずにきちんと実行できたりするんですなこれが (そんなわけで原因追及が手間取った)。
昔はこんな事なかったんだけどなぁ…。 ちなみにこのサイトの表示システムも同じApache+Perl FastCGIを使っているけど、 ご覧のとおり日本語のUTF-8表示できてるし。
ちなみに、システムはFreeBSD portsから突っ込んだapache-worker-2.2.17_1とap22-mod_fastcgi-2.4.6_1とp5-FastCGI-0.71_1の組み合わせ。
どうもググッてみると、昨年春のFastCGI 0.69あたりでこの仕様はエンバグされたようで、 それ以来全く直る気配がないっぽい。まあ、英語圏の人は困らないからねぇ…orz。
ちなみに、FCGIのPODの方にはこんな事まで書かれている始末(強調は私)。
FCGI.pm isn't Unicode aware, only characters within the range 0x00-0xFF are supported. Attempts to output strings containing characters above 0xFF results in a exception: (F) Wide character in %s.
さすがにちょっとそれは投げやりすぎやしないか(笑)。 まあ、これに続いて…
Users who wants the previous (FCGI.pm <= 0.68) incorrect behavior can disable the exception by using the bytes pragma.
{
use bytes;
print "\x{263A}";
}
↑こんな事が書いてあったので、 次のようなサブルーチンをこさえて、 「print "なんちゃら"」を全部「fcgiPrint("なんちゃら")」にしたら一応動くようになりましたわ。 それにしてもこれを"incorrect behavior"って言われても、 動かなきゃそもそもcorrectじゃねーよ。と思うんだがどうよ?
sub fcgiPrint($) { my $x = shift; utf8::decode($x); { use bytes; print $x; } }
まあ、余裕あったらコードを追っかけて直すのもやぶさかではないんだけど、 今そんな余裕はない…。 しかし、あんまりこの問題に関する日本語の資料が見つからないんだけど、 みんな困ってないのかな? それともFastCGI使っている人少ない?
あと、これは別問題なんだけど、 mod_perl2を使っているApacheでFastCGIを使うのがイマイチ不安定なんだよね。 なんでそんなこと必要なの、というと、 実はmod_perlは高速化のために使ってるわけじゃなくて、 Apache::AuthCookieを使うためにmod_perlを使っているわけ。 で、AuthCookie使う必要がないサイトとFastCGIのスクリプトを共有したいわけ。
まあ、それほどAuthCookieの方はアクセスがないだろうということで、 パフォーマンスを犠牲にして、httpd.confで
# AddHandler fastcgi-script .fcgiAddHandler cgi-script .fcgi
にしてしまえば問題ないんですけどね(FastCGIのスクリプトは単純なCGIスクリプトとしても動作する)。 でもDBのコネクションを乱造されるのも嫌なのでやっぱりこちらも解決したい。