Python + LigHTTPd + CGI:如何配置以执行整个子路径的单个脚本

2 投票
1 回答
1939 浏览
提问于 2025-04-18 18:36

我正在为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 个回答

5

在你的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

撰写回答