Python + LigHTTPd + CGI:如何配置以执行整个子路径的单个脚本
我正在为Python编写一组脚本,打算在网上使用。目前,我有一些测试脚本运行得很好,它们使用了import cgi
。
我想要的是FastCGI/WSGI的行为。具体来说,我希望能把某个网址下的所有请求都交给一个脚本来处理。比如说,假设用户访问的网址是http://www.example.com/script/run/1?param=true
。对于所有在/script
下的请求,我希望能运行一个特定的脚本,比如/opt/mypython/webscript.py
,这个脚本会使用import cgi
,并且能够接收到网址和GET参数。在这种情况下,我希望在脚本内部能看到一个包含/run/1
的参数,以及GET参数的字典。
出于安全考虑,理想情况下我们希望把脚本放在文档根目录之外。
我还希望能在我的脚本中使用x-sendfile
这个头信息。我知道FastCGI模块支持这个,但不确定标准的CGI模块是否支持。
我愿意转向FastCGI,但我不想重构我的代码。此外,我希望在开发过程中使用标准CGI,因为我查阅的唯一FastCGI实现(flup)会导致脚本被缓存,因此每次代码更改时都需要完全重启整个web服务器。而且,flup在使用CGI接口时需要以不同的方式工作,这意味着需要进行一些重大代码重写。
flup确实提供了一些方便的功能;它的environ
变量提供了一个PATH_INFO
参数,可以指定我上面提到的子路径。但标准的CGI模块没有提供所有这些便利,所以使用flup会需要重写代码,而在开发过程中频繁更改代码时,这样做非常低效。
所以,理想的解决方案是能够同时使用标准CGI和FastCGI,而不需要重写代码。这样在开发时我可以使用标准CGI,虽然性能会受到影响(因为每次都需要启动Python解释器),但当代码准备好投入生产时,可以轻松迁移到基于FastCGI的后端,以便最大限度地提高性能。
我正在使用当前版本的lighttpd。如果可能的话,我需要做些什么来配置lighttpd以实现这个目标呢?
1 个回答
在你的lighttpd配置中,创建一个别名,将 http://host/script
映射到你的CGI脚本的路径:
alias.url += ( "/script" => "/opt/mypython/webscript.py" )
为这个脚本启用CGI处理:
$HTTP["url"] =~ "^/script" {
cgi.assign = ( "" => "" )
}
创建一个CGI脚本,用来检查查询字符串和PATH_INFO环境变量:
import cgi, os, sys
print 'Content-Type: text/plain\n'
if 'PATH_INFO' in os.environ:
print os.environ['PATH_INFO']
form = cgi.FieldStorage()
if 'param' in form:
print form['param'].value
最后,通过网页浏览器调用这个脚本:
http://localhost/script/run/1?param=true
结果:
/run/1
true