Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python WSGI:多次读取env[';WSGI.input';]_Python_Pylons_Wsgi_Middleware - Fatal编程技术网

Python WSGI:多次读取env[';WSGI.input';]

Python WSGI:多次读取env[';WSGI.input';],python,pylons,wsgi,middleware,Python,Pylons,Wsgi,Middleware,我正在构建一个简单的web服务,它要求对所有请求进行签名。签名散列是使用包括请求主体的请求数据生成的。我希望有一个中间件组件来验证请求签名,如果签名无效,它将以错误响应。问题是中间件需要使用env['wsgi.input'].read()读取请求体。这会将请求主体字符串的指针提前到末尾,这使得执行链中的其他组件无法访问数据 有没有办法使env['wsgi.input']可以被读取两次 例: 您可以尝试从头开始查找,但您可能会发现,您必须将其替换为包含刚才读取内容的StringIO。以下规范处理该

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

有没有办法使env['wsgi.input']可以被读取两次

例:


您可以尝试从头开始查找,但您可能会发现,您必须将其替换为包含刚才读取内容的
StringIO

以下规范处理该确切问题,提供问题解释以及解决方案,包括源代码和需要考虑的特殊情况:

在environ['wsgi.input']上,Seeking的可能副本似乎不起作用,替换为StringIO,感觉有点脏,但谢谢。
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)