I created a WSGI middleware that stores the raw body from the environ['wsgi.input']
stream. I saved the value in the WSGI environ so I could access it from request.environ['body_copy']
within my app.
This isn't necessary in Werkzeug or Flask, as request.get_data()
will get the raw data regardless of content type, but with better handling of HTTP and WSGI behavior.
This reads the entire body into memory, which will be an issue if for example a large file is posted. This won't read anything if the Content-Length
header is missing, so it won't handle streaming requests.
from io import BytesIO
class WSGICopyBody(object):
def __init__(self, application):
self.application = application
def __call__(self, environ, start_response):
length = int(environ.get('CONTENT_LENGTH') or 0)
body = environ['wsgi.input'].read(length)
environ['body_copy'] = body
# replace the stream since it was exhausted by read()
environ['wsgi.input'] = BytesIO(body)
return self.application(environ, start_response)
app.wsgi_app = WSGICopyBody(app.wsgi_app)
request.environ['body_copy']