2011-11-23 22 views
3

这是一个奇怪的。 :)Perl CGI从不同的请求获取参数到当前的URL

我有一个脚本运行在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的&密码=栏

,我们承认我们的系统上的其他地方完全不同的脚本是一个查询字符串。

但是听起来很疯狂,似乎当用户访问带有查询字符串的URL时,该脚本正在查看的查询字符串是来自另一个脚本上先前请求的查询字符串。当然,脚本无法处理该操作并且不输出任何内容。

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

回答

2

这看起来是Apache 1.3,mod_perl 1.31,CGI.pm和Apache :: GTopLimit的有趣组合。

一个错误是在去年五月对记录CGI.pmRT #57184

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

CGI.pm为了注册一个清理处理程序清理它的所有高速缓存....(360线)

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

Apache::GTopLimit(如在bug报告中提到Apache::SizeLimit)也有这样的处理程序:

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

在pre 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流程的规模。

到目前为止所有的测试都指出这是问题,所以手指交叉了!