2016-04-08 5 views
1

Мне нужно загрузить RFC 1867 на сервер необработанных данных (без заголовков риффов) wav-файла. Я написал сценарий perl для этого. Похоже, это:RFC 1867 Загрузка файла из 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 также поддерживает многокомпонентные/form-данных контента, используемого для формы на основе загруженного файла, как указано в RFC 1867. You инициируйте этот формат содержимого, указав тип содержимого «форм-данных» как один из заголовков запросов. »

Однако серверу Content_Type = "form-data" не нравится, потому что он ожидает "multipart/form-data". Также Content_Length равно 0, и тело не загружается.

Что я делаю неправильно? Благодаря

+0

http://stackoverflow.com/questions/21273071/how-does-rfc-2854-obsolete-rfc-1867 стоит прочитать – Quentin

+0

не думаю, что это помогает. мы не имеем никакого контроля над сервером, который хочет загрузить RFC 1867 –

ответ

0

Вы не отправлял вывод:

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. Это потому, что:

Вы запускаете этот формат контента, указав тип содержимого «форм-данных» в качестве одного из заголовков запроса.

Другими словами, модуль 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; 

Ниже показана разница между указания пары ключ/значение V просто указав значение:

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? Не делай этого.

+0

, «как и все HTTP-запросы организуют свои данные» - это неверно, так как два стандартных кодировки запроса, которые вы можете запускать из стандартной HTML-формы, организуют их данные. – Quentin

+0

Спасибо, это очень помогает. Моя проблема состояла в том, что раздел Content не был в правильном формате. –