Отправить HTTP-запрос POST (данные XML), используя WWW :: Curl в perl - PullRequest
1 голос
/ 30 января 2012

Я хочу использовать WWW::Curl вместо LWP::UserAgent для отправки запроса на публикацию.Ниже приведен код, использующий LWP::UserAgent, который работает нормально.

my $agent = LWP::UserAgent->new(agent => 'perl post');
push @{ $agent->requests_redirectable }, 'POST';
my $header  = HTTP::Headers->new;
$header->header('Content-Type'  => "text/xml; charset=UTF-8");
$header->content_encoding('gzip');
utf8::encode( my $utf8_content = $args{content} );
sinfo $utf8_content;
$error->description($utf8_content);
$error->log;
my $request = HTTP::Request->new(POST => $args{url}, $header, $utf8_content);
my $response = $agent->request($request);

Мне нужно переписать этот код, используя WWW :: Curl, поскольку Curl работает быстрее, чем LWP.Я пробовал приведенный ниже код, но он возвращает мне код 35 в качестве ответа, что означает, что запрос недействителен.

my $curl = WWW::Curl::Easy->new();

$curl->setopt(WWW::Curl::Easy::CURLOPT_HEADER,1);
$curl->setopt(WWW::Curl::Easy::CURLOPT_URL,$self->uri());
$curl->setopt(WWW::Curl::Easy::CURLOPT_POST, 1);
$curl->setopt(WWW::Curl::Easy::CURLOPT_POSTFIELDS, $utf8_content);

my $response;

$curl->setopt(WWW::Curl::Easy::CURLOPT_WRITEDATA,\$response);

my $retcode = $curl->perform();

Данные, которые я передаю в запросе post ($ utf8_content), представляют собой строку xmlпример xml:

   <Request>
     <Source>
       <RequestorID Password="PASS" Client="Client" EMailAddress="email@address.com"/>
       <RequestorPreferences Language="en">
         <RequestMode>SYNCHRONOUS</RequestMode>
       </RequestorPreferences>
     </Source>
     <RequestDetails>
       <SearchRequest>
         <ItemDestination DestinationType="area" DestinationCode="XYZ"/>
         </ItemDestination>
       </SearchRequest>
     </RequestDetails>
   </Request> 

Более того, ответом будет также строка XML, которую можно получить из $ response;

Ответы [ 2 ]

2 голосов
/ 04 июля 2013

Вы пробовали $curl->setopt(CURLOPT_SSLVERSION, CURL_SSLVERSION_SSLv3);?

2 голосов
/ 30 января 2012

Теоретически это должно работать, но не работает. Проблема в том, что $utf8_content_gzip содержит \0 в середине, а C API усекает тело запроса. Если это ошибка, а не мое недоразумение, как разговаривать с WWW :: Curl, то либо исправьте ошибку, либо обойдите, просто не закодировав запрос.

use utf8;
use strictures;
use Devel::Peek qw(Dump);
use Encode qw(encode);
use HTTP::Response qw();
use IO::Compress::Gzip qw(gzip $GzipError);
use WWW::Curl::Easy qw();

my $utf8_content_gzip;
{
    my $utf8_content = encode('UTF-8', '<root>Třistatřicettři stříbrných stříkaček stříkalo přes třistatřicettři stříbrných střech.</root>', Encode::LEAVE_SRC | Encode::FB_CROAK);
    gzip(\$utf8_content, \$utf8_content_gzip)
        or die sprintf 'gzip error: %s', $GzipError;
}
Dump $utf8_content_gzip;

my $xml;
{
    my $curl = WWW::Curl::Easy->new;
    $curl->setopt(WWW::Curl::Easy::CURLOPT_HEADER(), 1);
    $curl->setopt(WWW::Curl::Easy::CURLOPT_URL(), 'http://localhost:5000');
    $curl->setopt(WWW::Curl::Easy::CURLOPT_HTTPHEADER(), ['Content-Type: text/xml; charset=UTF-8', 'Content-Encoding: gzip']);
    $curl->setopt(WWW::Curl::Easy::CURLOPT_POST(), 1);
    $curl->setopt(WWW::Curl::Easy::CURLOPT_POSTFIELDS(), $utf8_content_gzip);

    my $response;
    $curl->setopt(WWW::Curl::Easy::CURLOPT_WRITEDATA(), \$response);

    my $retcode = $curl->perform;
    if (0 == $retcode) {
        $response = HTTP::Response->parse($response);
        $xml = $response->decoded_content;
    } else {
        die sprintf 'libcurl error %d (%s): %s', $retcode, $curl->strerror($retcode), $curl->errbuf;
    }
}
...