1

我需要让 Python CGI 脚本做一些事情(一些安全检查),然后最终调用 Perl CGI 脚本,将它收到的任何内容(例如,POST 信息)传递到 Perl 脚本。

作为背景,我这样做的原因是我正在尝试将 Swish 搜索与 Mailman 列表档案集成。

Swish 搜索使用 swish.cgi,一个 Perl 脚本,但因为这些是私人列表档案,我不能只允许人们按照此页面上的建议直接调用 swish.cgi:http ://wpkg.org/Integrating_Mailman_with_a_Swish-e_search_engine#Mailman_configuration

我相信我需要做的是让 Mailman“私有”cgi-bin 文件(用 Python 编写)进行常规安全检查(调用一些 Mailman/python 模块),然后调用 swish.cgi 进行搜索(在验证用户在邮件列表中之后)。

本质上,我相信最简单的解决方案就是使用标准 mailman cgi-bin/private Python 脚本的变体来保护对 swish.cgi Perl 脚本的访问。

(我考虑过人们可以使用不受保护的 swish.cgi 进行搜索的想法,但人们将无法查看完整的结果,因为这些帖子在默认 Mailman 设置下已经受到密码保护......但问题是即使在搜索结果中显示 Swish 帖子摘录也可能会泄露机密信息,因此我必须将搜索本身的访问权限限制为仅限订阅者。)

如果有人对如何在不使用 Python-CGI-calls-Perl-CGI 的情况下解决整体问题有更好的了解,我会很乐意考虑“答案”。

只要知道我的目标是对标准 Mailman 安装进行少量(理想情况下不)更改。复制“私有”cgi-bin 脚本(其来源是 mailman-2.1.12/Mailman/Cgi/private.py)并更改调用 swish.cgi 很酷,但修改现有的私有 cgi-bin 脚本不会真的很酷。


这是我为测试答案所做的(使用os.execvperl 脚本替换 python 脚本,以便 perl 脚本继承 python 脚本的环境):

我创建了一个pythontest脚本:

import os
os.environ['FOO'] = 'BAR'
mydir = os.path.dirname(os.environ.get('SCRIPT_FILENAME'))
childprog = mydir + '/perltest'
childargs = []
os.execv(childprog, childargs)

然后是一个perltest脚本:

print "Content-type: text/html\n\n";
while (($key,$value) = each %ENV) {
  print "<p>$key=$value</p>\n";
}

然后我调用http://myserver.com/cgi-bin/pythontest并看到环境打印输出包含自定义 FOO 变量,因此子 perltest 进程已成功继承所有环境变量。

4

1 回答 1

1

我只是在这里陈述显而易见的事情,因为我对您的特定环境没有任何详细的了解。

If your python script is a genuine CGI and not a mod_python script or similar then it is just a regular process spawned to handle the one request. You can use os.execv to replace it with another process (e.g. the perl CGI) and the new process will inherit the current process' environment, stdin, stdout and stderr. This assumes that you don't need to read stdin for your security checks. It may also depend on whether your CGI is running in a restricted environment. execv is potentially dangerous and might be blocked in such an environment.

If you're running from a mod_python environment or if you need to peek at posted data (i.e. stdin) then the execv approach isn't available to you. You have two main alternatives.

You could run the perl CGI directly (e.g. look at the subprocess module) handing it a correct environment and feeding it the correct data to its stdin. You can the spool the returned data from its stdout raw (or cooked if needed) directly back to the web server.

Otherwise, you could make a local web request to run the CGI. This is likely to require a bit less knowledge about the server setup, but a bit more work in the python CGI to make and handle the HTTP request.

于 2010-01-27T08:14:51.283 回答