decoded_contentで文字コード明示するも化けらった

デコードするだけなら、この以下のコードをdecode前に足すだけで直ると思う

my @ct = grep { /^text/i } $res->header('content-type'); $res->header('content-type', @ct); print $res->decoded_content;

でもこれだけじゃあ答えが分かった、ってだけで後からこれを読んだ人のためにもならないので、以下どういう手順を取ったか説明してみる。

まず、最小限テストケースを用意。

実行するとばけらった。問題を確認した。この問題に関しては、decoded_content()が色々と問題があるのを事前に知っていたのでperl -dでデバッガモードで検証開始。

DB<1> HTTP::Message::decoded_content(/usr/local/lib/perl5/site_perl/5.8.8/HTTP/Message.pm:201): 201: if (my @ct = HTTP::Headers::Util::split_header_words( \ $self->header("Content-Type"))) {

あーなんかこのあたりでヘッダみてて怪しいなぁ・・・と思って、x @ctで中味を確認

DB<1> x @ct 0 ARRAY(0x8d334c) 0 'text/html' 1 undef 2 'charset' 3 'EUC-JP' 1 ARRAY(0x9f0be8) 0 'application/xhtml+xml' 1 undef 2 'charset' 3 'EUC-JP'

む。確かdecoded_content()はヘッダ内容とかでデコードの仕方を変えてるはず。これ、怪しいなぁ。その後、"n"でステップを薦めていくと以下の行に:

DB<2> n HTTP::Message::decoded_content(/usr/local/lib/perl5/site_perl/5.8.8/HTTP/Message.pm:293): 293: if ($ct && $ct =~ m,^text/,,) {

で、本来ならここに入っていかないとおかしいよね。テキストのデコードなんだから。でもそこに行かないで終わってしまった。ってことはapplication/xhtml+xmlがいけないんじゃね?ってことで以下のスクリプト。

use LWP::UserAgent; my $ua = LWP::UserAgent->new(); my $res = $ua->get('http://yugioh-wiki.net/index.php?%A5%C8%A5%C3%A5%D7%A5%DA%A1%BC%A5%B8'); my @ct = grep { /^text/i } $res->header('content-type'); $res->header('content-type', @ct); print $res->decoded_content;

これで見事動いた。これはバグかどうか微妙なところだよな。applicationで始まるMIME-Typeをデコードしろって言われても・・・ねぇ。xmlだったらテキスト、って判断すればよいのか?