如何通过CGI.pm获取整个请求体?

时间:2009-05-25 21:34:43

标签: perl cgi

我正在尝试编写一个Perl CGI脚本来处理XML-RPC请求,其中XML文档作为HTTP POST请求的主体发送。

CGI.pm模块在从HTTP请求中提取命名参数方面做得很好,但是我无法弄清楚如何让它给我整个HTTP请求体(即XML-RPC请求中的XML文档)我正在处理。)

如果不是CGI.pm,是否有另一个模块能够从请求中解析出这些信息?我宁愿不必从环境变量中“手动”提取这些信息。谢谢你的帮助。

3 个答案:

答案 0 :(得分:26)

您可以使用特殊参数名称POSTDATA获取原始POST数据。

my $q = CGI->new;
my $xml = $q->param( 'POSTDATA' );

或者,你可以直接阅读STDIN,而不是使用CGI.pm,但是你会失去CGI.pm所做的所有其他有用的东西。

POSTDATA技巧记录在优秀的CGI.pm文档here中。

答案 1 :(得分:14)

是的,可以使用POSTDATA,但只有在请求Content-Type尚未设置为'multipart / form-data'时才有效。

如果设置为'multipart / form-data',CGI.pm会自行处理内容并且POSTDATA未初始化。

因此,其他选项包括$cgi->query_string和/或$cgi->Dump

$cgi->query_string以GET格式(param=value&...)返回POST的内容,并且似乎没有办法简单地获取POST STDIN的内容,因为它们已通过在客户端。

因此,要获取POST请求的标准输入的实际内容,如果修改CGI.pm是您的选项,您可以修改第620行以将@lines的内容保存在变量的某处,如:

$self->{standard_input} = join '', @lines;

然后通过$cgi->{standard_input}访问它。

答案 2 :(得分:0)

要处理所有情况,包括 Content-Type multipart/form-data的情况,请先读取(并放回)原始数据,先于

use strict;
use warnings;

use IO::Handle;
use IO::Scalar;

STDIN->blocking(1); # ensure to read everything
my $cgi_raw = '';

{ 
  local $/; 
  $cgi_raw = <STDIN>;
  my $s;
  tie  *STDIN, 'IO::Scalar', \$s;
  print STDIN $cgi_raw;
  tied(*STDIN)->setpos(0);
}

use CGI qw /:standard/;
...