在perl中使用WWW::Curl发送HTTP POST请求(xml数据)

在perl中使用WWW::Curl发送HTTP POST请求(xml数据),perl,curl,xmlhttprequest,http-post,Perl,Curl,Xmlhttprequest,Http Post,我想使用WWW::Curl而不是LWP::UserAgent来发送post请求。 下面是使用LWP::UserAgent的代码,该代码运行良好 my $agent = LWP::UserAgent->new(agent => 'perl post'); push @{ $agent->requests_redirectable }, 'POST'; my $header = HTTP::Headers->new; $header->header('Content-

我想使用
WWW::Curl
而不是
LWP::UserAgent
来发送post请求。 下面是使用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\U内容)是一个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中检索

从理论上讲,这应该行得通,但行不通。问题是,<代码> $utf8xCoptTr.gZip 中包含了<代码> \ 0 < /C> >,而C API截断了请求体。如果这是一个bug,而不仅仅是我对如何与WWW::Curl对话的误解,那么要么修复bug,要么干脆不编码请求来解决问题

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;
    }
}
使用utf8;
使用狭窄;
使用Devel::Peek qw(转储);
使用编码qw(Encode);
使用HTTP::Response qw();
使用IO::Compress::Gzip qw(Gzip$Gzip错误);
使用WWW::Curl::Easy qw();
我的$utf8\u内容\u gzip;
{
我的$utf8_content=encode('UTF-8','Třistatřicettři střbrných střkaček stříkalo přes Třistatřicettři st brných střbrnýech,encode::LEAVEřřSRC|SRC|encode::FB|CROAK);
gzip(\$utf8\u内容,\$utf8\u内容\u gzip)
或死sprintf'gzip错误:%s',$gzip错误;
}
转储$utf8\u内容\u gzip;
我的$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);
我的回答;
$curl->setopt(WWW::curl::Easy::CURLOPT_WRITEDATA(),\$response);
my$retcode=$curl->perform;
如果(0==$retcode){
$response=HTTP::response->parse($response);
$xml=$response->解码内容;
}否则{
骰子sprintf'libcurl错误%d(%s):%s',$retcode,$curl->strerror($retcode),$curl->errbuf;
}
}

理论上,这应该是可行的,但事实并非如此。问题是,<代码> $utf8xCoptTr.gZip 中包含了<代码> \ 0 < /C> >,而C API截断了请求体。如果这是一个bug,而不仅仅是我对如何与WWW::Curl对话的误解,那么要么修复bug,要么干脆不编码请求来解决问题

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;
    }
}
使用utf8;
使用狭窄;
使用Devel::Peek qw(转储);
使用编码qw(Encode);
使用HTTP::Response qw();
使用IO::Compress::Gzip qw(Gzip$Gzip错误);
使用WWW::Curl::Easy qw();
我的$utf8\u内容\u gzip;
{
我的$utf8_content=encode('UTF-8','Třistatřicettři střbrných střkaček stříkalo přes Třistatřicettři st brných střbrnýech,encode::LEAVEřřSRC|SRC|encode::FB|CROAK);
gzip(\$utf8\u内容,\$utf8\u内容\u gzip)
或死sprintf'gzip错误:%s',$gzip错误;
}
转储$utf8\u内容\u gzip;
我的$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);
我的回答;
$curl->setopt(WWW::curl::Easy::CURLOPT_WRITEDATA(),\$response);
my$retcode=$curl->perform;
如果(0==$retcode){
$response=HTTP::response->parse($response);
$xml=$response->解码内容;
}否则{
骰子sprintf'libcurl错误%d(%s):%s',$retcode,$curl->strerror($retcode),$curl->errbuf;
}
}

您是否尝试过
$curl->setopt(CURLOPT\u SSLVERSION,curl\u SSLVERSION\u SSLv3)

您是否尝试过
$curl->setopt(CURLOPT\u SSLVERSION,curl\u SSLVERSION\u SSLv3)

备选方案:为了自动gzip压缩您的请求,至少在LWP版本中,您可以添加
$request->encode('gzip')
-它还将处理添加适当的
内容编码
标题。备选方案:为了自动gzip压缩您的请求,至少在LWP版本中,您可以添加
$request->encode('gzip')-它将处理添加适当的
内容编码
标题。hey thanx用于回复。我尝试使用和不使用编码,但仍然得到相同的返回码35。当我转储HTTP::Response对象时,内容为空:请参见下面的bless({''U content'=>'','U headers'=>bless({},'HTTP::headers'),'HTTP::Response');找不到导致错误的原因。。但无论如何,谢谢你在这件事上花了宝贵的时间。35是
CURLE\u SSL\u CONNECT\u错误
。我们需要完整的错误缓冲区,使用上面代码中的错误处理方法。下面是错误描述:libcurl错误35(SSL连接错误):gnutls_handshake()失败:已收到TLS致命警报。我想我需要添加一些额外的包或模块。。希望你能帮助我!!!谢谢。恐怕这个错误消息没有用。提供以下命令的输出:
openssl s_client-connect www.example.com:443 hello daxim,通过执行openssl s_client-connect URL。我收到URL的getservbyname失败。我也尝试了不同的端口(443:https,8080:http)。如果这意味着我无法连接到URL,那么如查询中所述,它将与HTTP::Request和LWP::Useragent一起工作。我不擅长网络领域的技术方面。。所以请给我一些启发