如何在AppEngine中添加修改响应体的WSGI中间件
添加一个只修改HTTP头部的中间件(比如FirePython)其实很简单,但当你调用webapp.WSGIApplication(environ, start_response)时,它返回的是[''],而不是一个包含内容的可迭代对象:
def __call__(self, environ, start_response):
...
response.wsgi_write(start_response)
return ['']
response.wsgi_write实际上是负责输出内容的:
def wsgi_write(self, start_response):
...
write = start_response('%d %s' % self.__status, self.__wsgi_headers)
write(body)
self.out.close()
这让通过WSGI中间件修改内容变得有点困难。通常我会这样做:
class Upperware:
def __init__(self, app):
self.wrapped_app = app
def __call__(self, environ, start_response):
for data in self.wrapped_app(environ, start_response):
return data.upper()
但这样不行,因为wrapped_app的返回值是['']。我该如何让Upperware中间件在Google AppEngine上工作呢?是什么设计决定导致了输出响应而不是返回响应呢?
1 个回答
3
如果你想要拦截请求体的写入,你需要自己定义 start_response
和 write
函数,像这样:
class Upperware(object):
def __init__(self, app):
self.wrapped_app = app
def __call__(self, environ, start_response):
def my_start_response(status, response_headers, exc_info=None):
write = start_response(status, response_headers, exc_info)
def my_write(body_data):
# Do your middleware handling of writes here
body_data = body_data.upper()
write(body_data)
return my_write
return self.wrapped_app(environ, my_start_response)
至于为什么 webapp 是这样写的,我就不太清楚了。不过,应该可以改变它的行为,让它返回一个迭代器或列表,而不会出问题,所以你可以随意 提交一个bug。