【问题标题】:RFC 1867 file upload from perl从 perl 上传 RFC 1867 文件
【发布时间】:2016-04-08 06:18:14
【问题描述】:

我需要将 RFC 1867 上传到 wav 文件的原始数据(没有 riff 标头)的服务器。我已经编写了一个 perl 脚本来执行此操作。看起来像这样:

my $wav = new Audio::Wav;
my $read = $wav->read($wavtoupload);
my $rawdata = $read->read_raw($read->length()); #raw data w/o riff

my $url = "http://thehost.com";
my $req = HTTP::Request->new();
$req = POST $url,
   Referer => 'hxxp://www.mydomain.com/some.php3', 
   Accept_Language => 'en-us',
   Content_Type => 'form-data',
   Accept_Encoding => 'wav',
   User_Agent => 'Mozilla/4.0',
   Host => 'www.mydomain.com',
   Connection => 'Keep-Alive',
   Content => [ $rawdata ];
print $req->as_string;

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

if ($resp->is_success) {
   #...
}

根据http://search.cpan.org/~ether/HTTP-Message-6.11/lib/HTTP/Request/Common.pm

“POST 方法还支持 RFC 1867 中指定的用于基于表单的文件上传的 multipart/form-data 内容。您可以通过指定内容类型 'form- data' 作为请求标头之一。”

但是,服务器正在接收 Content_Type = "form-data" 不喜欢它,因为它需要 "multipart/form-data"。 Content_Length 也为 0,并且没有上传正文。

我做错了什么?谢谢

【问题讨论】:

标签: perl upload wav multipart rfc


【解决方案1】:

您没有发布以下输出:

print $req->as_string;

您做错的一件事是您没有将数据组装成键/值对,这是所有 HTTP 请求组织数据的方式。

Content_Length 也是 0

这是因为所有数据都被用作键/值对的键部分,因此没有值,并且没有值的 Content-Length 为 0。

尽管如此,服务器不应该接收到标头:

Content_Type = "form-data"

对于原始请求,我得到:

POST http://thehost.com
Connection: Keep-Alive
Accept-Encoding: wav
Accept-Language: en-us
Host: www.mydomain.com
Referer: hxxp://www.mydomain.com/some.php3
User-Agent: Mozilla/4.0
Content-Length: 82
Content-Type: multipart/form-data; boundary=xYzZY

--xYzZY
Content-Disposition: form-data; name="mydata"

hello world
--xYzZY--

如您所见,Content-Type 标头是multipart/form-data。那是因为:

您可以通过指定内容类型来触发此内容格式 'form-data' 作为请求标头之一。

换句话说,perl 模块在实际请求中创建了标头Content-Type: multipart/form-data

这是我使用的代码:

use strict;
use warnings; 
use 5.020;
use Data::Dumper;
use HTTP::Message;
use HTTP::Request::Common;

my $rawdata = "hello world";
my $url = "http://thehost.com";

my $requ = POST $url,
   Referer => 'hxxp://www.mydomain.com/some.php3', 
   Accept_Language => 'en-us',
   Content_Type => 'form-data',
   Accept_Encoding => 'wav',
   User_Agent => 'Mozilla/4.0',
   Host => 'www.mydomain.com',
   Connection => 'Keep-Alive',
   Content => [ mydata => $rawdata ];

say $requ->as_string;

以下显示了指定键/值对与仅指定值之间的区别:

use strict;
use warnings; 
use 5.020;
use Data::Dumper;
use HTTP::Message;
use HTTP::Request::Common;

my $rawdata = "hello world";
my $url = "http://thehost.com";

my $requ = POST $url,
   Referer => 'hxxp://www.mydomain.com/some.php3', 
   Accept_Language => 'en-us',
   Content_Type => 'form-data',
   Accept_Encoding => 'wav',
   User_Agent => 'Mozilla/4.0',
   Host => 'www.mydomain.com',
   Connection => 'Keep-Alive',
   Content => [ 
       mykey => 'myValue',
       $rawdata, 
   ];


say $requ->as_string;

--output:--
POST http://thehost.com
Connection: Keep-Alive
Accept-Encoding: wav
Accept-Language: en-us
Host: www.mydomain.com
Referer: hxxp://www.mydomain.com/some.php3
User-Agent: Mozilla/4.0
Content-Length: 142
Content-Type: multipart/form-data; boundary=xYzZY

--xYzZY
Content-Disposition: form-data; name="mykey"  #<===HERE

myValue  #<======AND HERE
--xYzZY
Content-Disposition: form-data; name="hello world"  #<===COMPARED TO

        #<======COMPARED TO
--xYzZY--

裸值最终被用作键,并且由于没有值,Content-Length 最终为 0。

根据docs,您应该如何指定文件上传:

use strict;
use warnings; 
use 5.020;
use Data::Dumper;
use HTTP::Message;
use HTTP::Request::Common;

my $rawdata = "hello world";
my $url = "http://thehost.com";

my $requ = POST $url,
   Referer => 'hxxp://www.mydomain.com/some.php3', 
   Accept_Language => 'en-us',
   Content_Type => 'form-data',
   Accept_Encoding => 'wav',
   User_Agent => 'Mozilla/4.0',
   Host => 'www.mydomain.com',
   Connection => 'Keep-Alive',
   Content => [ 
       mykey => 'myValue',         #some other key/value pair
       cool_sounds => [undef,      #file upload key/value pair
                       'myfile.wav', 
                       Content => $rawdata
                      ] 

   ];


say $requ->as_string;

--output:--
POST http://thehost.com
Connection: Keep-Alive
Accept-Encoding: wav
Accept-Language: en-us
Host: www.mydomain.com
Referer: hxxp://www.mydomain.com/some.php3
User-Agent: Mozilla/4.0
Content-Length: 176
Content-Type: multipart/form-data; boundary=xYzZY

--xYzZY
Content-Disposition: form-data; name="mykey"

myValue
--xYzZY
Content-Disposition: form-data; name="cool_sounds"; filename="myfile.wav"

hello world
--xYzZY--

如果你需要为文件部分设置 Content-Type,你可以这样做:

use strict;
use warnings; 
use 5.020;
use Data::Dumper;
use HTTP::Message;
use HTTP::Request::Common;

my $rawdata = "hello world";
my $url = "http://thehost.com";

my $requ = POST $url,
   Referer => 'hxxp://www.mydomain.com/some.php3', 
   Accept_Language => 'en-us',
   Content_Type => 'form-data',
   Accept_Encoding => 'wav',
   User_Agent => 'Mozilla/4.0',
   Host => 'www.mydomain.com',
   Connection => 'Keep-Alive',
   Content => [ 
       mykey => 'myValue',         #some other key/value pair
       cool_sounds => [undef,      #file upload key/value pair
                       'myfile.wav', 
                       'Content-Type' => 'audio/x-wav', 
                       Content => $rawdata
                      ]  #=>If one of the values in the $form_ref is an array reference...

   ];


say $requ->as_string;

--output:--
OST http://thehost.com
Connection: Keep-Alive
Accept-Encoding: wav
Accept-Language: en-us
Host: www.mydomain.com
Referer: hxxp://www.mydomain.com/some.php3
User-Agent: Mozilla/4.0
Content-Length: 203
Content-Type: multipart/form-data; boundary=xYzZY

--xYzZY
Content-Disposition: form-data; name="mykey"

myValue
--xYzZY
Content-Disposition: form-data; name="cool_sounds"; filename="myfile.wav"
Content-Type: audio/x-wav

hello world
--xYzZY--

而且,如果您需要将文件部分的 Content-Disposition 设置为其他内容:

use strict;
use warnings; 
use 5.020;
use Data::Dumper;
use HTTP::Message;
use HTTP::Request::Common;

my $rawdata = "hello world";
my $url = "http://thehost.com";

my $requ = POST $url,
   Referer => 'hxxp://www.mydomain.com/some.php3', 
   Accept_Language => 'en-us',
   Content_Type => 'form-data',
   Accept_Encoding => 'wav',
   User_Agent => 'Mozilla/4.0',
   Host => 'www.mydomain.com',
   Connection => 'Keep-Alive',
   Content => [ 
       mykey => 'myValue',         #some other key/value pair
       cool_sounds => [undef,      #file upload key/value pair
                       'myfile.wav', 
                      'Content-Type' => 'audio/x-wav', 
                      'Content-Disposition' => 'file',
                       Content => $rawdata
                      ]

   ];


say $requ->as_string;

--output:--
POST http://thehost.com
Connection: Keep-Alive
Accept-Encoding: wav
Accept-Language: en-us
Host: www.mydomain.com
Referer: hxxp://www.mydomain.com/some.php3
User-Agent: Mozilla/4.0
Content-Length: 155
Content-Type: multipart/form-data; boundary=xYzZY

--xYzZY
Content-Disposition: form-data; name="mykey"

myValue
--xYzZY
Content-Disposition: file
Content-Type: audio/x-wav

hello world
--xYzZY--

请注意,在这种情况下,文件部分没有名称属性。

顺便说一句,是什么让您认为不发布您的use statements 有帮助?不要那样做。

【讨论】:

  • “这是所有 HTTP 请求组织数据的方式”——这不是真的,这只是您可以从标准 HTML 表单触发的两种标准请求编码组织数据的方式。
  • 谢谢,这很有帮助。我的问题只是内容部分的格式不正确。
猜你喜欢
  • 1970-01-01
  • 2023-03-13
  • 2015-10-10
  • 2012-07-16
  • 1970-01-01
  • 2014-04-09
  • 2011-10-05
  • 2012-12-17
  • 1970-01-01
相关资源
最近更新 更多