Perl LWP::UserAgent только читает первую строку опубликованного файла jpg

Я уверен, что это было задано, но я не смог найти хороший вопрос для моего ответа. У меня есть два сценария, один из которых создает сообщение с использованием LWP::UserAgent, а другой в основном получает данные, в данном случае я просто хочу написать файл. Файл действительно записывается, но его нельзя открыть, и его размер равен 1262, что наводит меня на мысль, что только часть его читается.

Вот что я делаю (стоит отметить, что я кодировал файл uri/base64 и передавал все через json, что работало, но моя новая задача - разделить файлы и передать все как параметры формы):

пост скрипт:

open (IMAGE, "./flower.jpg") or die "$!";
$raw_string1 = do{ local $/ = undef; <IMAGE>; };

my $req = HTTP::Request->new(POST => $url);
$req->content_type("application/x-www-form-urlencoded");
$req->content("json_string=$json&file_1=$raw_string1");

my $ua = LWP::UserAgent->new;
$res = $ua->request($req);
print $res->content;

Сценарий получателя:

$cgi = CGI->new;
my $json_post = $cgi->param('json_string');
my $file_1 = $cgi->param('file_1');

open my $fh, '>', "$path/flower.jpg" or die $!;
binmode $fh;
print $fh $file_1;
close $fh;

Спасибо за помощь заранее!

2 ответа

Решение

Как упоминалось ранее, у вас есть проблема с кодировкой. Решение простое:

my $req = HTTP::Request->new(POST => $url, [
   json_string => $json,
   file_1      => $raw_string1,
]);

что коротко для

my $req = HTTP::Request->new(POST => $url,
   Content_Type => 'application/x-www-form-urlencoded',
   Content => [
      json_string => $json,
      file_1      => $raw_string1,
   ]
);

Это гораздо более типично для использования multipart/form-data загружать файлы, хотя. И если вы это сделаете, вы даже можете позволить HTTP::Request загрузить файл для вас!

my $req = HTTP::Request->new(POST => $url,
   Content_Type => 'multipart/form-data',
   Content => [
      json_string => $json,
      file_1      => [ 'flower.jpg' ],
   ]
);

CGI.pm справится с этим без проблем. См. Раздел документов, озаглавленный "ОБРАБОТКА ПОЛЯ ЗАГРУЗКИ ФАЙЛА".

Вы не кодируете $raw_string1 данные, прежде чем вставить его в тело HTTP POST. Это означает, что если данные в flower.jpg включает в себя шестнадцатеричный байт 0x26 (& char) - скажем, в позиции 1263 - тогда данные POST будут выглядеть так:

json_string={ ... JSON data ... }&file_1=...1262 bytes of raw JPEG data...&...more JPEG data...

... что означает, что все, что разбирает тело формы для переменных формы, будет усечено file_1 после 1262 байта.

Я бы рекомендовал продолжать кодировать $raw_string1 данные с base64 или чем-то подобным, даже если вы передаете их как свою собственную переменную POST, а не добавляете их в данные JSON.

Другие вопросы по тегам