MacOSXのport updateで文字化け問題

だんだん名前が変わってきました。

残障害まとめ

  • ○解消した障害
    • ioncube_loaderのロード失敗→php52に変更することで解消
    • Apache経由の名前解決(PHPのgetaddr等)で失敗→Apache再起動では駄目で、システム再起動して解消
    • Apacheが再起動後起動しない。→launchctlで再設定することで解消
    • MySQLが再起動後起動しない。→plistとwrapperを復旧して、launchctlで再設定することで解消
  • ×残ってる障害
    • PHPの一部表示で文字化け


どうもダメなのはframeset使ってる奴で、最初のframe要素だけ文字化けするのです。
なんなんだろうこれは。
UTF-8のページが化けるとかそういう類かと思ってたけど
出力がShift_JISUTF-8の両方があって、メタタグのContent-Typeでのcharset指定も間違ってない。

なのに、特定のフレームだけ文字化けして嫌だわ。

尚、ブラウザ毎に挙動が違う

Internet Explorer6 SP2 ちゃんと表示される
Internet Explorer8 文字化けのフレームのPHPファイルがダウンロードされる(しかも失敗する)
Firefox 3.5.5 文字化け(上記Screen Shot)
Safari4.0(530.17) 文字化け(同様)
Google Chrome 3.0.195.33 文字化け(同様)

フレーム単体で呼び出しても同じ挙動であることが確認出来た。

HTTPヘッダ調査

そろそろ問題の切り分けをちゃんとやらないとな。もっと簡単に解決されると思ってた。
いろいろ巡ってる中にHTTPヘッダがおかしいものを吐いているケースがあるという情報を得て
Live HTTP HeadersというFirefoxのアドオンを入れて調べてみた。

正しく表示されているページとされていないページのヘッダの差分として、正しい方に下記の出力があった。

Vary: Accept-Encoding
Content-Encoding: gzip

別の表示されないページで調べてみても、出てない方には上記ヘッダが無かった。
これが原因だとすると、gzip圧縮したデータを送ってるのに、圧縮してるよ。ってヘッダが無いとか?
エンコーディングをいろいろ弄っても一向に改善しないあたり、その線が濃厚だ。

ちょっと調べた

Vary: User-Agent
 ブラウザから送信された User-Agent に応じて proxy はコンテンツキャッシュの利用を決める

mod_gzip で Vary: * を send すると IE で SSL の挙動が変になる - drk7jp

クライアント⇒サーバのリクエストヘッダでは Accept-Encoding: でブラウザ側が利用可能な圧縮形式を提示できます。
対してサーバ⇒クライアントのレスポンスヘッダでは Content-Encoding: でデータ本文の圧縮形式を通知できるようです。

Content-Encoding: gzipのテスト

Accept-Encodingは文字化けする場合もしない場合も

Accept-Encoding: gzip,deflate

が帰ってきている。やっぱり、圧縮してるくせに圧縮してるよって通知をサボってる線がさらに濃厚になってきた。

この辺を差し込んでるのは、Apache1.x系ではmod_zgip、Apache2.x系ではmod_deflateらしい。

httpd.confで設定する場合
LoadModule deflate_module modules/mod_deflate.so
SetOutputFilter DEFLATE
php.iniで設定する場合
zlib.output_compression On
zlib.output_compression_level -1
zlib.output_handler

phpinfo()で確認するとphp側でzlib圧縮設定をしているようだ。

圧縮を外してみる。

Live HTTP Headersでは、HTTPヘッダを弄って送信できるので

Accept-Encoding: gzip,deflate

を削除して文字化けするページを確認してみたら表示された!!!

暫定対策としてFirefoxのabout:configを使ってnetwork.http.accept-encodingの値を"gzip,deflate"から"identity"に変更して回避。
自宅鯖なので、利用者は制限されてるから帯域けちるよりzip/unzip分のオーバーヘッドをけちった方がよさそうだから圧縮を外す。

この設定をしていて気がついたけど、はてなダイヤリー(ここ)のテーマ(スタイルシート)
http://d.hatena.ne.jp/theme/hatena-darkgray/hatena-darkgray.css
は、Accept-Encodingがブラウザから来ない場合gzip圧縮して送ってきて、さらにContent-Encodinヘッダが来ないので文字化けする。

はてなアイデアとかで指摘した方がいいんだろうか。

圧縮の設定をやめる。

  • zlib圧縮の設定を調べる
    • php.iniでの設定を外してみる。→解決した。
    • httpd.confで調べてみる。→設定されてなかった。

ちょっとPHPのバージョンを上げたかっただけなのに、大事になりすぎだ。
Macportsがだんだん嫌いになってきた。今の問題はMacportsの問題とちと違うかもしれないけ

PHP 5.2.10のこのバグはちょっと似てる。
PHP Bugs: #48994: zlib.output_compression does not ouput HTTP headers when set to a string value
zlib.output_compressionの設定値に1じゃなくて、trueとかOnとか文字で指定するとコンテンツは圧縮されるけどヘッダが出ない。

特定のパターンだけ圧縮したことを示すヘッダが出ないなんて、厄介だなー。

PHP5.2.11のバグなんだろうか、コードがいまいちなんだろうか。
とりあえず使わないことで修復されました。