在某些方面,wsgi 将 cgi 所做的一些事情抽象为纯 python 函数调用,没有副作用。
cgi 程序的“输入”是进程环境,在os.environ 和sys.stdin 中。这样一个程序的输出是sys.stdout,错误是从sys.stderr到达服务器日志。
wsgi 应用程序是一个带有两个* 参数的 python 函数,通常称为 environ(将是 dict)和 start_response(将是另一个函数)。
第一个参数是dict,包含cgi 程序可以在os.environ 中获得的所有内容,但它还包含几个额外的键。值得注意的是,它包含"wsgi.input",一个类似文件的对象,它代替sys.stdin 用于请求正文。
cgi 程序使用sys.stdout 作为 HTTP 响应行、响应标头和响应正文。在 wsgi 程序中,前两个作为参数传递给 start_response 参数。 wsgi 响应正文没有**写入文件;相反,它是从 app 函数返回的。
典型的 CGI 程序可能如下所示:
import os, sys
request_size = int(os.environ.get("HTTP_CONTENT_LENGTH", "0"))
person = sys.stdin.read(request_size)
response = "Hello %s!\n" % person
print "Status: 200 OK"
print "Content-Type: text/plain"
print "Content-Length: %d" % len(response)
print
print response
等效的 wsgi 程序如下所示:
def myApp(environ, start_response):
request_size = int(environ.get("HTTP_CONTENT_LENGTH", "0"))
wsgi_input = environ.get("wsgi.input")
person = wsgi_input.read(request_size) if request_size and wsgi_input else ""
response = "Hello %s!\n" % person
start_response("200 OK",
[("Content-Type", "text/plain"),
("Content-Length", str(len(response)))]
return [response]
* 出于技术原因,有一个可选的第三个参数,主要用于“中间件”
** 出于与旧 Web 框架的兼容性,start_response() 返回类似文件可以写入的对象,但不建议这样做。在您的情况下,它可能会简化转换,但由于无论如何都需要进行侵入性更改,所以看看您是否可以避免它。