Entiende el código correctamente antes de aplicarlo a tu trabajo y si ttienes algo que aportar puedes decirlo en los comentarios.
Solución:
Usar request.get_data()
para obtener los datos sin procesar, independientemente del tipo de contenido. Los datos se almacenan en caché y posteriormente puede acceder request.data
, request.json
, request.form
a voluntad.
Si accedes request.data
primero llamará get_data
con un argumento para analizar primero los datos del formulario. Si la solicitud tiene un tipo de contenido de formulario (multipart/form-data
, application/x-www-form-urlencoded
o application/x-url-encoded
), entonces se consumirán los datos sin procesar. request.data
y request.json
aparecerá vacío en este caso.
request.stream
es el flujo de datos sin procesar que el servidor WSGI pasa a la aplicación. No se realiza ningún análisis al leerlo, aunque por lo general desea request.get_data()
en lugar de.
data = request.stream.read()
La transmisión estará vacía si fue leída previamente por request.data
u otro attribute.
Creé un middleware WSGI que almacena el cuerpo sin procesar del environ['wsgi.input']
Arroyo. Guardé el valor en el entorno WSGI para poder acceder a él desde request.environ['body_copy']
dentro de mi aplicación.
Esto no es necesario en Werkzeug o Flask, ya que request.get_data()
obtendrá los datos sin procesar independientemente del tipo de contenido, pero con un mejor manejo del comportamiento de HTTP y WSGI.
Esto lee todo el cuerpo en la memoria, lo que será un problema si, por ejemplo, se publica un archivo grande. Esto no leerá nada si el Content-Length
falta el encabezado, por lo que no manejará las solicitudes de transmisión.
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']
Si conservas algún titubeo o disposición de aclarar nuestro división te inspiramos escribir una aclaración y con gusto lo interpretaremos.