我正在尝试使用特定的Web服务,我可以使用以下命令成功执行上载:
curl -X POST --header "Transfer-Encoding: chunked" -d @Downloads/file.pdf https://some.webservice/upload
我得到了一个json回复表明成功。
但是,我无法弄清楚如何对WWW :: Mechanize做同样的事情。
$mech->post("https://" . $server . "/upload", Content_Type => 'multipart/form-data', Content => [upID => $upid, name => $dlfile, userID => 0, userK => 0, file_0 => [$dlfile]]);
这会收到一个类似的json响应,其中包含一个很大的错误消息。
我是否需要先显式设置Transfer-Encoding标头?还有其他一些技巧吗?谷歌对此没有太多了解,Perlmonks也没有,而且文档有点迟钝。
答案 0 :(得分:4)
你真的需要WWW::Mechanize
吗?它是LWP::UserAgent
的子类,具有附加功能,提供类似浏览器的功能,如填写和提交表单,单击链接,带有“后退”操作的页面历史记录等。如果您不需要所有这些你也可以直接使用LWP::UserAgent
无论哪种方式,post
方法都会从LWP::UserAgent
继承,并且可以直接使用它
发送分块POST
的方法是将Content
设置为对子例程的引用。子程序每次调用时都必须返回下一个数据块,最后一个空字符串或undef
当没有更多要发送时
数据是否应该是JSON字符串?
最简单的方法是编写一个返回闭包的工厂子程序,比如这个
sub make_callback {
my ($data) = shift;
sub { substr($data, 0, 512, "") }
}
然后你可以像这样打电话给post
my $payload = to_json(...);
$mech->post(
"https://$server/upload",
Content_Type => 'multipart/form-data',
Content => make_callback($payload)
);
请注意,所有这些都是未经测试的
答案 1 :(得分:3)
您可以使用HTTP :: Request :: StreamingUpload
来完成my $starttime = time();
my $req = HTTP::Request::StreamingUpload->new(
POST => $url,
path => $file,
headers => HTTP::Headers->new(
'Transfer-Encoding' => 'chunked'
),
);
my $gen = $req->content;
die unless ref($gen) eq "CODE";
my $total = 0;
$req->content(sub {
my $chunk = &$gen();
$total += length($chunk);
print "\r$total / $size bytes ("
. int($total/$size*100)
. "%) sent, "
. int($total/1000/(time()-$starttime+1))
. " k / sec ";
return $chunk;
});
my $resp = $ua->request($req);
print "\n";
unless ($resp->is_success) {
die "Failed uploading the file: ", $resp->status_line;
}
my $con = $resp->content;
return $con;