FastCGI、Perl和Exit
在过去的几周里,我一直在磨砺一个大型的、有几十年历史的代码库的性能,在这里,有人建议我应该看看FastCGI或HTTP::Engine之类的东西。我发现使用FastCGI非常简单,但有一个问题我发现答案参差不齐 我读过的一些文档说,对于通过FastCGI运行的脚本,永远不应该调用FastCGI、Perl和Exit,perl,fastcgi,psgi,Perl,Fastcgi,Psgi,在过去的几周里,我一直在磨砺一个大型的、有几十年历史的代码库的性能,在这里,有人建议我应该看看FastCGI或HTTP::Engine之类的东西。我发现使用FastCGI非常简单,但有一个问题我发现答案参差不齐 我读过的一些文档说,对于通过FastCGI运行的脚本,永远不应该调用exit,因为这会损害持久加载脚本的整个概念。其他人说这无关紧要。我的代码在很多地方都使用exit,在这些地方确保没有任何东西继续执行是很重要的。例如,我有调用授权检查的受限访问组件: use MyCode::Autho
exit
,因为这会损害持久加载脚本的整个概念。其他人说这无关紧要。我的代码在很多地方都使用exit,在这些地方确保没有任何东西继续执行是很重要的。例如,我有调用授权检查的受限访问组件:
use MyCode::Authorization;
our $authorization = MyCode::Authorization->new();
sub administration {
$authorization->checkCredentials();
#...Do restricted access stuff.
}
为了尽可能避免代码中出现错误,允许某人在不应该访问这些函数的情况下访问这些函数,checkCredentials
在通过登录页面生成用户友好的响应(如果答案是用户没有适当的凭据),然后使用exit()结束该过程。例如:
sub checkCredentials {
#Logic to check credentials
if ($validCredential) {
return 1;
}
else {
# Build web response.
# Then:
exit;
}
}
}
我使用了它,这样我就不会不小心忽略了一些导致安全漏洞的东西。目前,如果提供了正确的凭据,调用例程可以安全地假定它只能从checkCredentials
中恢复控制
但是,我想知道是否需要删除这些调用以充分利用FastCGI。FCGI的$req->Finish()
(或PSGI中HTTP::Engine的等效版本)是否足以替代
我读过一篇文章,说你不应该在通过FastCGI运行的脚本上调用exit
您不希望进程退出,因为使用FastCGI的目的是使用单个进程来处理多个请求(以避免加载时间等)
因此,您要做的是覆盖exit,以便结束特定于请求的代码,而不是FastCGI请求循环
您可以覆盖退出,但必须在编译时这样做。因此,使用一个标志来表示超越是否处于活动状态
我们的$override\u exit=0;
开始{
*核心::全局::退出=子(;$){
如果$OVERRIDE\u EXIT,则禁用“EXIT\u OVERRIDE\n”;
CORE::exit($\u0]//0);
};
}
while(get_request()){
#其他设置。。。
评估{
本地$override_exit=1;
处理请求();
};
我的$exit\u被调用=$@eq“exit\u覆盖\n”;
如果调用了$@&!$exit,则记录错误($@);
如果调用了$Exit,\u,则记录\u错误(“调用Exit\n”);
#其他清理。。。
}
但这会创建一个可能被无意中捕获的异常。因此,让我们使用last
我们的$override\u exit=0;
开始{
*核心::全局::退出=子(;$){
无警告qw(退出);
如果$OVERRIDE\u EXIT,则上次退出\u OVERRIDE;
CORE::exit($\u0]//0);
};
}
while(get_request()){
#其他设置。。。
我的$exit_被称为=1;
退出超控:{
本地$override_exit=1;
eval{handle_request()};
如果$@,则记录错误($@);
$exit_被调用=0;
}
如果调用了$Exit,\u,则记录\u错误(“调用Exit\n”);
#其他清理。。。
}
这确实是一段很酷的代码,尽管我对替代方案仍有点不确定,也就是说,链接到“重复”问题堆栈溢出注释并没有完全触及我的困惑点。如果我覆盖退出
,如何确保相同的等价项?例如,该处理不会继续,但在FastCGI处理的情况下,我立即返回阻塞,而循环等待另一个请求。我重新打开了它,但使用替代方案没有意义,因为您应该已经在使用它。等价什么?如果您问“如果我覆盖退出,如何确保我立即返回阻塞while循环以等待另一个请求。等价物?”,这正是答案告诉您的方法。抱歉,我不清楚这一点。所以handle_request()部分确保我回到while循环?哦,我想我应该提到{…}
(作为一个语句,而不是散列构造函数)在技术上是一个循环。在文档(IIRC)中称为“裸循环”,它是一个只执行一次的循环。因此,last
只需退出该循环即可。(标签处理嵌套。)答案与