Полагаю, я неправильно использую LWP :: Simple :: get, но я не понимаю, как это исправить. Моя первая попытка была простой
perl -e 'use LWP::Simple; print get("http://localhost/wtf.txt");'
, но это не сработало. wtf.txt
содержит один символ в кодировке UTF-8 u+00f6
(т. Е. ö
). Используя wget
и xxd
, я убедился, что HTTP-сервер отправляет правильную строку заголовка Content-Type: text/plain; charset=utf-8
и что содержимое соответствует ожиданиям. Но приведенный выше код perl вместо этого возвращает u+00f6
в кодировке ISO-8859-1.
Я думал, что это простая проблема с кодировкой с простым исправлением, но копнув глубже, я обнаружил, что это не так просто, как я надеялся. Я создал второй файл wtf2.txt
с одним символом u+30e4
в кодировке UTF-8 (т.е. ヤ
) и получил оба с помощью следующего кода Perl:
#!/usr/bin/perl
use LWP::Simple;
$wtf=get("http://localhost/$ARGV[0]");
$wtf2=pack("H*",unpack("H*",$wtf));
print $wtf;
print "\n";
print $wtf2;
print "\n$wtf\n$wtf2\n";
print (unpack("H*",$wtf)."\n");
При выборке wtf.txt
этот код записывает 4 раза u+00f6
в своей форме, закодированной в ISO-8859-1, за которой следует f6
(его форма в кодировке ISO-8859-1 в шестнадцатеричной форме). До сих пор все как раньше. Но при получении wtf2.txt
этот код записывает u+30e4
в кодировке UTF-8, за которой следует u+00e4
(т.е. ä
) в ISO-8859-1, u+30e4
в UTF-8, u+00e4
в UTF-8, e4
(ISO-8859- 1 из u+00e4
в шестнадцатеричном формате).
Учитывая, что u+30e4
и u+00e4
не имеют ничего общего друг с другом, кроме того, что последний является побитовой маской / усеченной версией первого, я ожидаю, что внутри LWP :: Simple происходит не только перекодирование, но и некоторое усечение. Я склонен отправить отчет об ошибке в LWP :: Simple, но я все еще надеюсь на простое исправление и / или объяснение.
Кстати, ни одна из описанных проблем не возникает, если я заменяю вторую и третью строку на $wtf=<>;
и просто читаю файлы из stdin
вместо того, чтобы получать их через LWP :: Simple :: get.
Я тестировал это с помощью perl 5.14.2 и libwww 6.04 на Debian 7.