Python WSGI: reading env ['wsgi.input'] more than once

I am creating a simple web service that requires all requests to be signed. A signature hash signal is generated using the request data, including the request body. My desire is to have a middleware component that verifies the signature of the request, responding with an error if the signature is invalid. The problem is that the middleware needs to read the request body using env ['wsgi.input']. Read (). This speeds up the pointer to the line of the request body to the end, which makes the data inaccessible to other components further in the execution chain.

Is there a way to make env ['wsgi.input'] read twice?

Example:

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) 
+4
source share
2 answers

You may try returning to the beginning, but you may find that you have to replace it with a StringIO containing just read.

+3
source

The following specification addresses this exact problem, explaining the problem, as well as the solution, including source code and special cases to consider: http://wsgi.readthedocs.org/en/latest/specifications/handling_post_forms.html

+1
source

All Articles