AppEngine 混淆 - CGI, WSGI 兼容?
我有点困惑。
如果AppEngine应该能运行使用WSGI的应用程序……
# somewhere in a webapp.RequestHandler
env = dict(os.environ.items())
for key, value in env.items():
self.response.out.write(key+': '+value+'<br/>')
req_uri = wsgiref.util.request_uri(env)
……那为什么env
里面没有PEP 333列出的那些必须存在的变量呢?这导致wsgiref.util.request_uri()
抛出了一个KeyError
错误?
我基本上是在写一些库,这些库需要在AppEngine或者普通的Apache + modwsgi环境下都能工作。我以为只要写一个符合WSGI
标准的应用就可以了,但似乎AppEngine本身……并不是这样?
2 个回答
据我所知,pep 333 并没有说必须把所有的 wsgi 环境变量都放进 os.environ
,除非是在模拟 CGI 的情况下。它只是说 wsgi 环境变量应该包含这些内容。
在 wsgi 应用程序中,environ 字典就是传递给你的 wsgi 应用函数的部分。在 GAE(谷歌应用引擎)中,你可以通过 request.environ
来访问 wsgi environ 字典。所以我觉得你的代码应该更像这样:
# somewhere in a webapp.RequestHandler
env = self.request.environ
for key, value in env.iteritems():
self.response.out.write(key+': '+value+'<br/>')
req_uri = wsgiref.util.request_uri(env)
在这里提到的 environ
是一个包含特定于 WSGI 的键的环境变量,它是传递给 WSGI 应用程序的。PEP-333 并没有要求这个值必须是 os.environ
。对于 CGI 应用程序来说,很多键会出现在 os.environ
中,因为网关服务器提供了这些信息,而 CGI 到 WSGI 的网关接口(比如 wsgiref.handlers.CGIHandler
)只需要在调用 WSGI 应用程序之前添加特定于 WSGI 的键。
为了更清楚地说明,当 PEP-333 提到 environ
时,它并不意味着 os.environ
。
编辑:google.appengine.ext.webapp.Request
显然是继承自 webob.Request
。因此,webapp 处理程序可以像下面这样访问 WSGI 的 environ
。
class MainPage(webapp.RequestHandler):
def get(self):
dosomethingwith(self.request.environ)