Python WSGI:不止一次读取env ['wsgi.input']

时间:2011-05-22 19:56:16

标签: python pylons wsgi middleware

我正在构建一个简单的Web服务,需要签署所有请求。使用包括请求主体的请求数据生成签名散列。我的愿望是拥有一个验证请求签名的中间件组件,如果签名无效则响应错误。问题是中间件需要使用env ['wsgi.input']读取请求体.read()。这会将请求正文字符串的指针前进到结尾,这使得数据在执行链中的其他组件中无法访问。

有没有办法让env ['wsgi.input']可以读两次?

例如:

from myapp.lib.helpers import sign_request
from urlparse import parse_qs
import json

class ValidateSignedRequestMiddleware(object):
    def __init__(self, app, secret):
        self._app = app
        self._secret = secret

    def __call__(self, environ, start_response):
        auth_params = environ['HTTP_AUTHORIZATION'].split(',', 1)
        timestamp = auth_params[0].split('=', 1)[1]
        signature = auth_params[1].split('=', 1)[1]

        expected_signature = sign_request(
            environ['REQUEST_METHOD'],
            environ['HTTP_HOST'],
            environ['PATH_INFO'],
            parse_qs(environ['QUERY_STRING']),
            environ['wsgi.input'].read(),
            timestamp,
            self._secret
        )
        if signature != expected_signature:
            start_response('400 Bad Request', [('Content-Type', 'application/json')])
            return [json.dumps({'error': ('Invalid request signature',)})]

        return self._app(environ, start_response)

2 个答案:

答案 0 :(得分:3)

你可以尝试回到起点,但你可能会发现你必须用包含你刚刚读出的内容的StringIO替换它。

答案 1 :(得分:1)

以下规范处理该确切问题,提供问题的解释以及包括源代码和特殊情况的解决方案: http://wsgi.readthedocs.org/en/latest/specifications/handling_post_forms.html