使用perl CGI.pm获取原始请求正文

时间:2018-07-30 17:57:42

标签: perl cgi cgi.pm

我正在使用Apache和Perl CGI构建Web服务器,该服务器处理发送给它的POST请求。处理部分要求我从请求中获取完全未处理的数据并验证其签名。

客户端发送两种不同的POST请求:一种将内容类型设置为application/json,另一种将内容类型设置为application/x-www-form-urlencoded

我能够使用application/json来获取cgi->param('POSTDATA')数据。但是,如果我对application/x-www-form-urlencoded数据(即cgi->param('payload'))进行同样的操作,我会得到数据,但已被解码。我想要原始URL编码格式的数据。即我想要客户端发送的未处理数据。

我这样做是为了验证Slack发送的请求。

2 个答案:

答案 0 :(得分: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/;
...

答案 1 :(得分:-1)

尽管我不确定哪个Perl模块可以为您处理所有事情,但这是一个基本的总结。

您的HTML表单应提交到.cgi文件(或任何其他正确定义的处理程序)。

原始请求与此类似:

POST HTTP/1.1
UserAgent: Mozilla/5.0
Content-Length: 69
Host: 127.0.0.1
(More headers depending on situation and then a single blank line)

(Message Body Containing data)
username=John&password=123J (example)

https://en.wikipedia.org/wiki/List_of_HTTP_header_fields

将发生的情况是,可以使用环境变量和stdin通过CGI(不是CGI perl模块,也称为CGI.pm)获得此数据(使用EV传递标头字段,使用stdin传递消息正文)。

在Perl中,我认为您需要阅读以下电动汽车:http://perldoc.perl.org/Env.html

这是标准输入:https://perlmaven.com/read-from-stdin

从那里开始,您可以根据需要进行处理。

请仔细阅读以下任何内容。您可以在HTTP标头之一或消息正文中向您发送格式错误的信息,例如100GB的有效数据,这可能会破坏您的行为或造成危险的系统调用等。在将数据传递到其他位置之前,必须进行消毒。