如何向AppEngine添加一个修改响应主体的WSGI中间件

时间:2010-12-10 16:33:55

标签: python google-app-engine wsgi

添加仅修改HTTP标头的中间件(如FirePython)非常简单,但是当您调用webapp.WSGIApplication(environ,start_response)时,它会返回['']而不是带有正文的iterable:

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的返回值是['']。如何在Google AppEngine中使Upperware中间件工作?什么是导致编写响应而不是返回响应的设计决策?

1 个答案:

答案 0 :(得分:3)

如果要拦截对请求正文的写入,则需要定义自己的start_responsewrite函数,如下所示:

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是这样写的,我恐怕不能说。应该可以改变它的行为以产生迭代器或列表,而不会破坏任何东西,所以请随意file a bug