Отправить запрос потокового HTTP в Perl - PullRequest
0 голосов
/ 28 сентября 2018

Я хочу отправить запрос XML с использованием протокола потоковой передачи HTTP.где передача-кодировка "чанкована".В настоящее время я использую LWP :: UserAgent для отправки транзакции XML.

my $userAgent = LWP::UserAgent->new;
my $starttime = time();
my $response = $userAgent->request(POST $url,
Content_Type => 'application/xml',
Transfer_Encoding => 'Chunked',
Content => $xml);


print "Response".Dumper($response);

Но я получаю http код состояния 411 Length Required.Что означает «клиентский код ответа об ошибке указывает, что сервер отказывается принимать запрос без определенного» * ​​1005 *

Как мы можем справиться с этим при отправке запроса в чанке?

Ответы [ 2 ]

0 голосов
/ 29 сентября 2018

LWP :: UserAgent API не предназначен для отправки потока, но он способен сделать это с минимальным взломом.

use strict;
use warnings qw( all );

use HTTP::Request::Common qw( POST );
use LWP::UserAgent        qw( );

my $ua = LWP::UserAgent->new();

# Don't provide any content.
my $request = POST('http://stackoverflow.org/junk',
   Content_Type => 'application/xml',
);

# POST() insists on adding a Content-Length header.
# We need to remove it to get a chunked request.
$request->headers->remove_header('Content-Length');

# Here's where we provide the stream generator.
my $buffer = 'abc\n';
$request->content(sub {
   return undef if !length($buffer);                # Return undef when done.
   return substr($buffer, 0, length($buffer), '');  # Return a chunk of data otherwise.
});

my $response = $ua->request($request);
print($response->status_line);

Используя прокси (Fiddler), мы видим, что это действительно такотправьте разделенный запрос:

Screenshot of proxy showing a chunked request was used


Нет смысла использовать разделенный запрос, если у вас уже есть весь документ под рукой, как в приведенном вами примере.Вместо этого, скажем, хотел загрузить выходные данные какого-либо внешнего инструмента, поскольку он производил свои выходные данные.Для этого вы можете использовать следующее:

open(my $pipe, '-|:raw', 'some_tool');
$request->content(sub {
   my $rv = sysread($pipe, my $buf, 64*1024);
   die $! if !defined($rv);
   return undef if !$rv;
   return $buf;
});
0 голосов
/ 29 сентября 2018

Но я получаю http код состояния 411 Необходимая длина.

Не все серверы понимают запрос с фрагментарной полезной нагрузкой, даже если это стандартизировано в HTTP / 1.1 (но не в HTTP / 1.0).Например, nginx поддерживает разбиение на фрагменты только в запросе начиная с версии 1.3.9 (2012), см. Есть ли способ избежать ошибок nginx 411 Content-Length? .Если сервер не понимает запрос с использованием chunked-кодировки, вы ничего не можете сделать со стороны клиента, то есть вы просто не можете использовать chunked-кодировку передачи.Если у вас есть контроль над сервером, убедитесь, что сервер действительно его поддерживает.

Я также никогда не испытывал браузеров, отправляющих такие запросы, вероятно, так как они не могут гарантировать, что сервер будет поддерживать такой запрос.Я видел только мобильные приложения, в которых сервер и приложение управляются одной и той же стороной, и, таким образом, поддержка запросов по частям может быть гарантирована.

...