QUERY_STRINGが勝手にデコードされた
IRCログを検索するCGIをでっちあげようとしていたら,日本語の扱いに困った.ASCIIの範囲だとうまくいくのに「ほげ」とかだと化けてしまう.これはRubyのNKFライブラリの判定精度の問題なのかな,と思って <input type="hidden" value="日本語文字列">
がどのように渡されるかで判定することにした*1.しかしどうやってもCGI内の各種エンコード済みのものと一致しない.あれあれ,と思いとりあえず単純なクエリからテスト: "foo" はOK.次に "!@#$%^&*(){}|" を試したら '#' でぷつりと途切れる.Rubyのライブラリ cgi
の CGI#params
がそもそもおかしいのだ.信じ難いがこれはRubyのバグ? じゃあライブラリには頼るまい,と環境変数 QUERY_STRING
を見るとここですでに途切れている.しかもURLエンコーディングが勝手にデコードされてるではないか.先輩が環境変数一覧を表示するCGIで試して下さったところ, QUERY_STRING
はおかしくなっているが(完全に一般的ではない) REQUEST_URI
ならOKということが分かった.よって REQUEST_URI
から自分でクエリを切り分けて亊無きを得た.2時間くらい手間取ったが... これが昨日の夜のこと.
とりあえず当該CGIでは問題は解決したものの,このままでは新サーバにまともにCGIが置けない.そう思ってあれこれとApacheのマニュアルを調べる.環境変数,CGI,suexec,関連モジュール... しかし分からない.そもそも環境変数を書き換えるなどという機能のモジュールなど載ってないのだ??? そして昼過ぎ,ふと別のことをしていたら,ふと閃いた.こないだWebDAVサービスを整備してたときに入れた mod_encoding がすげーーーー怪しいじゃないか,と. "mod_encoding QUERY_STRING" でググると,出るわ出るわ同じ症状の報告と対策情報がいっぱい.あーあ.自分で入れたモジュールのことなんて,Apacheの標準添付マニュアルいくら読んでも載ってるわけないよなぁ.むしろそういうのをまず疑うべきだったのに.アホくさい.検索CGIも普通に CGI#params
を使うように戻して,テストして... という一つ一つが単純なことでも時間を取られるのが鬱陶しい.
んで結論: とりあえず安直にディレクティブ Location
を使うことにした*2.mod_encodingに当てるパッチもあるようだが,私の場合は必要ない((Re: Netscape + Apache 日本語で検索できない? に投稿されたパッチが必要なのは「mod_encodingが有効になっているディレクトリの特定のサブディレクトリでのみmod_encodingを無効にしたい」ときだけ.私の場合,WebDAV用ディレクトリの下はみなmod_encodingが有効になっていてくれていいので,単に )).Location
でいいのだ.
なおmod_encodingの設定で AddClientEncoding SJIS "Microsoft .* DAV"
は入れないように注意.これはweb上の古い文書(@ITとか)で散見される設定だが,ワイルドカード ".*" を使うと以降の選択肢が無視されてしまうとのこと.DefaultClientEncoding
があれば十分なのだ.
<IfModule mod_encoding.c> <Location /dav> EncodingEngine on NormalizeUsername on SetServerEncoding UTF-8 DefaultClientEncoding JA-AUTO-SJIS-MS SJIS AddClientEncoding "cadaver/" EUC-JP </Location> </IfModule>
このようなものを mods-available/dav.conf
に保存し, mods-enabled-members/dav.conf
として貼ったsymlinkを経由して sites-available/default
内の <VirtualHost *:443>
内で Include
している.こうすればHTTPSでないと /dav
は "404: Object Not Found" になる.