如何使用WWW进行分块传输编码上传:机械化?

如何使用WWW进行分块传输编码上传:机械化?

问题描述:

我试图使用特定的网络服务,我可以成功地用下面的命令进行上传:如何使用WWW进行分块传输编码上传:机械化?

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

仅当使用回调时才使用分块的原因是因为内容长度是事先已知的,并且如果内容长度已知,则没有必要使用分块编码。 – ikegami

你可以使用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; 
+0

谢谢,这个解决方案似乎工作正常... json响应现在没有错误。除了(以前的)错误之外,我还有一些东西需要弄清楚,但是我想我现在可以休息了。 –

你真的需要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) 
); 

请注意,所有的这是未经测试

+0

我可以直接使用LWP,我只是不想诉诸system()ing curl命令,也不想重写python或其他东西中已有的大脚本。感谢这一点,我会去修补它。尝试跟随我在开发工具中看到的一样,并且我不认为我理解这些工作如何,直到您指出。 –

+0

有没有办法与文件内容之外的其他领域做到这一点?我可以使文件上传,但它绊倒了其他几个缺失值(尽我所知)。 –