Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: GUI > Принять данные POST напрямую


Автор: alezzz 14.12.2011, 12:14
Есть скрипт который принимает xml от программы-клиента. Программа шлет xml методом POST, я вижу в логах апача что приходит постом, но при разборе того что пришло Data::Dumper-ом вижу что-то непонятное.

Принимаю так:
Код

use CGI qw(:cgi);

my $query = new CGI;


Далее Dumper показывает:
Код

...
'.parameters' => [
                                    '<?xml version'
                                  ],
...
'param' => {
                              '<?xml version' => [
                                                              '"1.0" encoding="utf-8"?> ...

как-будто данные пришли GET-ом. Пришлось сделать "костыль" и принять как:
Код

my $cont = $query->param('<?xml version');
$cont = '<?xml version=' . $cont;


Все работает, но глаз режет. Начал разбираться как это правильнее сделать. Пробовал принять из STDIN в разных вариантах, например:
Код

while (<>){
    print;
}

Но ничего на выходе нет.

Читаю man по СGI, но что-то не нахожу как принять напрямую данные.

Добавлено через 5 минут и 5 секунд
Извините, не в том разделе тему сделал 

Автор: Pfailed 14.12.2011, 18:20
Как именно от клиента приходит?

Код

POST  XXX
Header1
Header2
Header3
Content-Type: application/x-www-form-urlencoded
Content-Length: xxx

<xml>
...
</xml>


Или без x-www-form-urlencoded?

Автор: alezzz 14.12.2011, 21:08
CONTENT_TYPE = application/x-www-form-urlencoded; Charset=UTF-8

Автор: DurRandir 14.12.2011, 22:48
Cуществует магический параметр, который вернёт вам "сырые" данные POST'a: 

Код

my $xml = $query->param('POSTDATA');

Автор: alezzz 15.12.2011, 00:09
ага, существует smile, осталось это объяснить программе-клиенту:
Код

$VAR1 = bless( {                 
          '.parameters' => [                                    
          '<?xml version'                                  
          ],                 
          'use_tempfile' => 1,                 
          '.charset' => 'ISO-8859-1',                 
          '.fieldnames' => {},       
          'param' => {          
                    '<?xml version' => [                                      
                        '"1.0" encoding="UTF-8"?><xml_request name="sms_send"> ... лишнее удалил ... </xml_request>'
                                                   ]
                              },                 
          'escape' => 1               
          }, 'CGI' );


и программа написана не под мой скрипт, у меня просто шлюз конвертирующий в другой протокол, т.е. как-то ведь работало

Автор: DurRandir 15.12.2011, 03:36
А _зачем_ вы делаете дамп этого $query? Т.е. вы попробовали, и вам тело запроса этот метод не вернул? Или вернул в каком-то другом виде? Т.к. то, что вы показываете, это не результат, полученный из $query->param('POSTDATA').

Автор: alezzz 15.12.2011, 10:27
Цитата(DurRandir @  15.12.2011,  03:36 Найти цитируемый пост)
то, что вы показываете, это не результат, полученный из $query->param('POSTDATA').

а где же возмутся эти данные? я так понимаю что метод param берет данные из хеша с указаным в методе ключем.

Всетаки дело в CONTENT_TYPE = application/x-www-form-urlencoded. Если отправлять в text/xml то приходит в POSTDATA. Я отправил xml с Content-type: application/x-www-form-urlencoded и получил такую же структуру, т.е.  param(''<?xml version'') = '"1.0" encoding="UTF-8"....

и как правильно забрать данные переданные через POST при CONTENT_TYPE = application/x-www-form-urlencoded?

Автор: alezzz 15.12.2011, 10:57
Посмотрел HTTP::Request::Common, если передавать с контент-типом application/x-www-form-urlencoded не xml а данные как при GET запросе, например:
Код

my $query = q{name1=value1&name2=value2};

my $req = HTTP::Request->new( POST => 'http://localhost/test.cgi');
$req->content_type('application/x-www-form-urlencoded');
$req->content($query);

То все логично принимается, param('name1') = value1, param('name2') = value2. Видимо проблема нерешаема, криворукие разработчики неправильно сделали отправку xml.

Из того же HTTP::Request::Common
Цитата

By default we will initialize a request using the application/x-www-form-urlencoded content type.

_____
Просьба к модераторам переместить тему в "Perl: разработка для Web"

Автор: DurRandir 15.12.2011, 19:30
В общем, действительно, если content-type=application/x-www-form-urlencoded, то POSTDATA нет. Если перед скриптом стоит nginx, и принимать он должен только такие "кривые" запросы, то укажите для этого location'a 

fastcgi_param   CONTENT_TYPE "application/none"

Автор: alezzz 15.12.2011, 19:52
DurRandir, на хостинге апач, но за совет спасибо.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)