Python WSGI:多次阅读 env['wsgi.input']

rr.*_*rr. 5 python pylons middleware wsgi

我正在构建一个需要对所有请求进行签名的简单 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)
Run Code Online (Sandbox Code Playgroud)

Ign*_*ams 3

您可以尝试返回到开头,但您可能会发现必须将其替换为包含StringIO您刚刚读出的内容。