2015-03-05 2 views
2

Я пишу быстрый скрипт, чтобы выполнить поданный файл и вернуть этот контент пользователю.Получение тела HTTP-запроса POST с использованием mod-perl 2

Мой тестовый код выглядит следующим образом:

#!/path/to/bin/perl 
use strict; 
use warnings; 
use utf8; 

use Apache2::RequestRec; 
use Apache2::RequestIO; 

my ($xmlin, $accepts) = (q{}, q{}); 
my $format = 'json'; 

# read the posted content 
while (
    Apache2::RequestIO::read($xmlin, 1024) 
    ) {}; 

{ 
    no warnings; 
    $accepts = $Apache2::RequestRec::headers_in{'Accepts'}; 
} 
if ($accepts) { 
    for ($accepts) { 
    /application\/xml/i && do { 
     $format = 'xml'; 
     last; 
    }; 
    /text\/plain/i && do { 
     $format = 'text'; 
     last; 
    }; 
    } ## end for ($accepts) 
} ## end if ($accepts) 
print "format: $format; xml: $xmlin\n"; 

Этот код не компилировать с Undefined subroutine &Apache2::RequestIO::read

Если я закомментируйте время цикла, код работает нормально.

Apache2::RequestIO К сожалению, код протягивается через Apache2::XSLoader::load __PACKAGE__; поэтому я не могу проверить фактический код .... но я не понимаю, почему это не работает

(да, у меня тоже попробовал $r->read(...), безрезультатно)

+0

Вы можете оставить апачские конфигурации? – rouzier

ответ

0

Я думаю, что у меня есть хорошая идея, почему ваш код не работает.

Модуль Apache2 :: RequestIO добавила новую функциональность Apache2 :: RequestRec.

Другими словами, чтобы добавить новые методы/функции в пространство имен Apache2 :: RequestRec.

Я бы сначала сменил Apache2 :: RequestIO :: прочитал Apache2 :: RequestRec :: read.

Если это не работает, используйте обработчик.

У меня есть код, который работает, который делает подобный вещь

В вашем httpd.conf

PerlSwitches -I/path/to/module_dir 
PerlLoadModule ModuleName 
PerlResponseHandler ModuleName 

ModuleName.pm

package ModuleName; 
use strict; 
use warnings; 
use Apache2::RequestIO(); 
use Apache2::RequestRec(); 
use Apache2::Const -compile => qw(OK); 
sub handler { 
    my ($r) = @_; 
    { 
     use bytes; 
     my $content = ''; 
     my $offset = 0; 
     my $cnt = 0; 
     do { 
      $cnt = $r->read($content,8192,$offset); 
      $offset += $cnt; 
     } while($cnt == 8192); 
    } 
    return Apache2::Const::HTTP_OK; 
} 
0

Я также использовать Apache2::RequestIO читать тело:

sub body { 
    my $self = shift; 

    return $self->{ body } if defined $self->{ body }; 
    $self->apr->read($self->{ body }, $self->headers_in->get('Content-Length')); 

    $self->{ body }; 
} 

В этом случае вы должны подклассифицировать оригинал Apache2::Request. Особенно обратите внимание на our @ISA = qw(Apache2::Request);

Я не знаю, почему, но стандартный метод body возвращают меня:

$self->body  # {} 
$self->body_status # Missing parser 

когда Content-Type является application/json. Поэтому я так обходила это. Затем разобрать тело себе:

sub content { 
    my $self = shift; 

    return $self->{ content } if defined $self->{ content }; 

    my $content_type = $self->headers_in->get('Content-Type'); 
    $content_type =~ s/^(.*?);.*$/$1/; 

    return unless exists $self->{ $content_type }; 

    return $self->{ content } = $self->{ $content_type }($self->body, $self); 
} 

где:

use JSON; 
sub new { 
    my ($proto, $r) = @_; 

    my $self = $proto->SUPER::new($r); 
    $self->{ 'application/json' } = sub { 
     decode_json shift; 
    }; 
    return $self; 
} 
Смежные вопросы