【问题标题】:Perl CGI gets parameters from a different request to the current URLPerl CGI 从对当前 URL 的不同请求中获取参数
【发布时间】:2011-11-23 18:48:12
【问题描述】:

这是一个奇怪的问题。 :)

我有一个在 Apache 1.3 下运行的脚本,带有 mod_perl 的 Apache::PerlRun 选项。它使用标准的 CGI.pm 模块。它是在繁忙的服务器上定期访问的脚本,通过 https 访问。

URL 通常类似于...

/script.pl?action=edit&id=47049

然后以通常的方式将其带入 Perl...

my $action = $cgi->param("action");
my $id = $cgi->param("id");

这已经成功运行了几年。然而,我们本周开始收到来自访问此脚本并获得空白页面的客户的支持请求。我们已经有如下一行,将当前 URL 放入我们用于客户报告页面问题的表单中......

$cgi->url(-query => 1);

当我们查看页面源代码时,该命令的结果是相同的 URL,但查询字符串完全不同。

/script.pl?action=login&user=foo&password=bar

我们识别为来自系统其他地方完全不同的脚本的查询字符串。

无论这听起来多么疯狂,似乎当用户使用查询字符串访问 URL 时,脚本看到的查询字符串来自另一个脚本的先前请求。当然脚本不能处理那个动作并且什么也不输出。

我们运行了一些自动化测试脚本来查看这种情况发生的频率,但并非每次都如此。为了给混合带来一些额外的混乱,在 Apache 重新启动后,问题似乎最初完全消失,只是稍后再出现。所以不管是什么原因,重启都会以某种方式缓解,但我们看不到 Apache 怎么可能接受一个用户的请求并将其与另一个用户混合。

【问题讨论】:

    标签: perl apache cgi mod-perl


    【解决方案1】:

    这似乎是 Apache 1.3、mod_perl 1.31、CGI.pm 和 Apache::GTopLimit 的有趣组合。

    去年 5 月针对 CGI.pm 记录了一个错误:RT #57184

    其中还引用了CGI.pm params not being cleared?

    CGI.pm 注册一个清理处理程序以清理它的所有缓存....(第 360 行)

    $r->register_cleanup(\&CGI::_reset_globals);
    

    Apache::GTopLimit(就像错误报告中提到的Apache::SizeLimit)也有这样的处理程序:

    $r->post_connection(\&exit_if_too_big) if $r->is_main;
    

    在 mod_perl 1.31 之前的版本中,post_connection 和 register_cleanup 似乎会压入堆栈,而在 1.31 中,GTopLimit 似乎破坏了CGI.pm 条目。因此,如果您的 GTopLimit 函数因为 Apache 进程变大而触发,那么 CGI.pm 将不会被清理,让它在您下次使用时返回相同的参数。

    解决办法好像是把CGI.pm的360行改成;

    $r->push_handlers( 'PerlCleanupHandler', \&CGI::_reset_globals);
    

    显式地将处理程序推送到列表中。

    我们重新启动 Apache 暂时解决了这个问题,因为它减小了所有进程的大小并且让 GTopLimit 没有理由触发。

    我们假设它在过去几周内出现,因为我们通过新开发增加了 Apache 进程的大小,其中包括以前没有的东西。

    到目前为止,所有测试都表明这是问题所在,所以祈祷吧!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-01-09
      • 2017-04-11
      • 2012-12-25
      • 2019-05-12
      • 1970-01-01
      • 1970-01-01
      • 2014-04-18
      • 1970-01-01
      相关资源
      最近更新 更多