如何使用 CGI.pm 获取整个请求正文?
Posted
技术标签:
【中文标题】如何使用 CGI.pm 获取整个请求正文?【英文标题】:How can I get the entire request body with CGI.pm? 【发布时间】:2021-08-21 20:09:09 【问题描述】:我正在尝试编写一个 Perl CGI 脚本来处理 XML-RPC 请求,其中 XML 文档作为 HTTP POST 请求的主体发送。
CGI.pm 模块在从 HTTP 请求中提取命名参数方面做得很好,但我不知道如何让它给我整个 HTTP 请求正文(即 XML-RPC 请求中的 XML 文档我正在处理)。
如果不是 CGI.pm,是否有另一个模块能够从请求中解析出这些信息?我宁愿不必从环境变量中“手动”提取这些信息。感谢您的帮助。
【问题讨论】:
【参考方案1】:您可以使用特殊参数名称 POSTDATA 获取原始 POST 数据。
my $q = CGI->new;
my $xml = $q->param( 'POSTDATA' );
或者,您可以直接读取 STDIN 而不是使用 CGI.pm,但是您会失去 CGI.pm 所做的所有其他有用的东西。
POSTDATA 技巧记录在优秀的 CGI.pm 文档here 中。
【讨论】:
确保您的 POST 请求的内容类型不是application/x-www-form-urlencoded
或multipart/form-data
,否则POSTDATA
将为空。像text/html
这样的其他任何东西都可以。编辑 - 哦,下面提到了 2 个答案...【参考方案2】:
是的,可以使用 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
访问。
【讨论】:
【参考方案3】:要处理所有情况,包括 Content-Type 为 multipart/form-data
的情况,请读取(并放回)原始数据,before CGI 会这样做。
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/;
...
【讨论】:
以上是关于如何使用 CGI.pm 获取整个请求正文?的主要内容,如果未能解决你的问题,请参考以下文章