[SPb-pm] AnyEvent::HTTPD vs POST

Ruslan Kuksa perl-list at spb.csat.ru
Tue Jun 17 04:10:12 PDT 2014


Еще раз спасибо за ответы.

Очень похоже, что данные пропадают.
Пропатчил как умею:
# diff /usr/share/perl5/AnyEvent/HTTPD/Util.pm 
/usr/share/perl5/AnyEvent/HTTPD/Util.pm-orig
36c36
< my $cont2 = {};
---
 > $cont = {};
43c43
< push @{$cont2->{$name}}, [$val, ''];
---
 > push @{$cont->{$name}}, [$val, ''];
45c45
< $#pars ? $cont2: $cont;
---
 > $cont

Если что не так, научите как лучше.
Новый код такой:

    sub parse_urlencoded {
    my ($cont) = @_;
    my (@pars) = split /[\&\;]/, $cont;
    my $cont2 = {};

    for (@pars) {
    my ($name, $val) = split /=/, $_;
    $name = url_unescape ($name);
    $val = url_unescape ($val);

    push @{$cont2->{$name}}, [$val, ''];
    }
    $#pars ? $cont2: $cont;
    }


Теперь работают и тот и другой content-type.
Наверное, надо добавить свойство "force_multipart" и выставлять его для таких 
неисправимых клиентов, как мой.

Как лучше поступить? Понимаю, что оно уже работает и можно просто забить. Но 
хочется правильно и навсегда.

17.06.2014 14:08, Andrey Chernomyrdin пишет:
> Ну с application/x-www-form-urlencoded тут с клиентом нужно что-то 
> предпринимать, так как справедливо заметил Denis Ibaev <dionys at gmail.com 
> <mailto:dionys at gmail.com>> в самом коде есть такой кусок:
> sub handle_request {
> my ($self, $method, $uri, $hdr, $cont) = @_;
>
> $self->{keep_alive} = ($hdr->{connection} =~ /keep-alive/io);
>
> my ($ctype, $bound) = _content_type_boundary ($hdr->{'content-type'});
>
> if ($ctype eq 'multipart/form-data') {
> $cont = $self->decode_multipart ($cont, $bound);
>
> } elsif ($ctype =~ /x-www-form-urlencoded/o) {
> $cont = parse_urlencoded ($cont);
> }
>
> $self->event (request => $method, $uri, $hdr, $cont);
> }
> То есть если в заголовке есть x-www-form-urlencoded значит фрейморк пытаеся 
> отпарсить все это, причем если не распарсил - случилась беда, оригинала не 
> остается, как я понял из кода (нужно проверить т.к. смотрел по-диагонали)
>
>
> 2014-06-17 13:50 GMT+04:00 Ruslan Kuksa <perl-list at spb.csat.ru 
> <mailto:perl-list at spb.csat.ru>>:
>
>     Спасибо за ответы.
>
>     Это оно самое. При отправке через curl --data-binary, данные печатаются
>
>     print $req->content();
>
>     А как быть с application/x-www-form-urlencoded?
>     Что надо предпринимать?
>
>     17.06.2014 13:03, Andrey Chernomyrdin пишет:
>
>         Просто content лучше использовать когда передается что-то типа
>         XML/JSON,например если сделать запрос таким образом:
>         curl -s \
>         -H 'Content-Type: text/xml' \
>         -H 'SOAPAction: ""' \
>         --data-binary '<soapenv:Envelope
>         xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
>         xmlns:api="http://localhost/api">
>         <soapenv:Header/><soapenv:Body><api:getOrganizationsRequest/></soapenv:Body></soapenv:Envelope>'
>         \
>         http://localhost:9090/to-post
>
>         То в $req->content получишь то, что указанно в --data-binary
>
>
>         2014-06-17 12:51 GMT+04:00 Denis Ibaev <dionys at gmail.com
>         <mailto:dionys at gmail.com> <mailto:dionys at gmail.com
>         <mailto:dionys at gmail.com>>>:
>
>
>         В документации же сказано:
>
>         content - Returns the request content or undef if only parameters for
>         a form were transmitted.
>
>         А при Content-Type: application/x-www-form-urlencoded он думает, что
>         есть параметры. Это видно в
>         https://metacpan.org/source/ELMEX/AnyEvent-HTTPD-0.93/lib/AnyEvent/HTTPD/HTTPConnection.pm#L302
>
>         sub handle_request {
>         my ($self, $method, $uri, $hdr, $cont) = @_;
>
>         $self->{keep_alive} = ($hdr->{connection} =~ /keep-alive/io);
>
>         my ($ctype, $bound) = _content_type_boundary ($hdr->{'content-type'});
>
>         if ($ctype eq 'multipart/form-data') {
>         $cont = $self->decode_multipart ($cont, $bound);
>
>         } elsif ($ctype =~ /x-www-form-urlencoded/o) {
>         $cont = parse_urlencoded ($cont);
>         }
>
>         $self->event (request => $method, $uri, $hdr, $cont);
>         }
>
>
>         17 июня 2014 г., 12:00 пользователь Ruslan Kuksa
>         <perl-list at spb.csat.ru <mailto:perl-list at spb.csat.ru>
>         <mailto:perl-list at spb.csat.ru <mailto:perl-list at spb.csat.ru>>> написал:
>
>         > задел меня доклад по AnyEvent, решил переписать одну фигню.
>         > Клиент отправляет данные на сервер методом POST:
>         >
>         > POST / HTTP/1.1
>         > Host: localhost:8080
>         > Accept: */*
>         > Content-Length: 1797
>         > Content-Type: application/x-www-form-urlencoded
>         > Expect: 100-continue
>         >
>         > Как вытащить те самые 1797 байтов данных?
>         > Чтение документации очень помогло, я узнал что это возможно, но не
>         узнал
>         > как. (:
>
>         --
>         Денис Ибаев
>         _______________________________________________
>         Spb-pm mailing list
>         Spb-pm at pm.org <mailto:Spb-pm at pm.org> <mailto:Spb-pm at pm.org
>         <mailto:Spb-pm at pm.org>>
>
>         http://mail.pm.org/mailman/listinfo/spb-pm
>
>
>
>
>         -- 
>         With best, Andrey Chernomyrdin
>
>
>         _______________________________________________
>         Spb-pm mailing list
>         Spb-pm at pm.org <mailto:Spb-pm at pm.org>
>         http://mail.pm.org/mailman/listinfo/spb-pm
>
>
>     _______________________________________________
>     Spb-pm mailing list
>     Spb-pm at pm.org <mailto:Spb-pm at pm.org>
>     http://mail.pm.org/mailman/listinfo/spb-pm
>
>
>
>
> -- 
> With best, Andrey Chernomyrdin
>
>
> _______________________________________________
> Spb-pm mailing list
> Spb-pm at pm.org
> http://mail.pm.org/mailman/listinfo/spb-pm



More information about the Spb-pm mailing list