1

我正在使用 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 发出的请求。

4

2 回答 2

0

要处理所有情况,包括Content-Type为时的情况,请在CGI之前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/;
...
于 2019-10-07T13:35:50.303 回答
-2

虽然我不确定哪个 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

将会发生的是,这些数据可通过 CGI(不是 CGI perl 模块,即 CGI.pm)使用环境变量和标准输入(使用 EV 传递标头字段,使用标准输入传递消息体)。

在 Perl 中,我认为你需要这个来阅读那些 EV: http: //perldoc.perl.org/Env.html

这要阅读标准输入:https ://perlmaven.com/read-from-stdin

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

阅读其中任何内容时请务必小心。您可能会在其中一个 HTTP 标头或消息正文中收到格式错误的信息,例如 100GB 有效数据,这可能会对您造成严重破坏或危险的系统调用等。在将数据传递到其他地方之前,必须进行消毒。

于 2018-08-01T18:44:51.507 回答