diff --git a/adiuvare/integrations/flask.py b/adiuvare/integrations/flask.py index 5d2f8f9..af88a75 100644 --- a/adiuvare/integrations/flask.py +++ b/adiuvare/integrations/flask.py @@ -1,4 +1,5 @@ import asyncio +import io import json from werkzeug.wrappers import Request, Response @@ -14,6 +15,10 @@ def __init__(self, app, guard, flask_app=None) -> None: self._flask = flask_app def __call__(self, environ, start_response): + content_length = int(environ.get("CONTENT_LENGTH") or 0) + body_bytes = environ["wsgi.input"].read(content_length) if content_length > 0 else b"" + environ["wsgi.input"] = io.BytesIO(body_bytes) + req = Request(environ) raw_ip = req.headers.get("x-forwarded-for", "") ip = raw_ip.split(",", 1)[0].strip() or req.remote_addr or "127.0.0.1" @@ -21,7 +26,7 @@ def __call__(self, environ, start_response): if route_cfg.get("exempt"): return self._app(environ, start_response) - body_text = req.get_data(as_text=True) + body_text = body_bytes.decode("utf-8", errors="replace") query_text = req.query_string.decode("utf-8") if req.query_string else "" payload = ctx_payload(body_text, query_text) diff --git a/tests/test_flask.py b/tests/test_flask.py index 31aab73..792d69c 100644 --- a/tests/test_flask.py +++ b/tests/test_flask.py @@ -461,4 +461,26 @@ def test_threadsafe_items_returns_all_identities(): assert len(result) == 5 for i in range(5): - assert f"user-{i}" in identities \ No newline at end of file + assert f"user-{i}" in identities + + +def test_flask_request_json_readable_after_middleware_inspection(): + + app = Flask(__name__) + guard = Guard() + guard.use(app, framework="flask") + + @app.post("/notes") + def create_note(): + data = request.get_json(silent=True) + assert data is not None + return jsonify(received=data), 201 + + client = app.test_client() + res = client.post( + "/notes", + json={"title": "Shopping List", "body": "milk, bread"}, + headers={"x-user-id": "u1"}, + ) + assert res.status_code == 201 + assert res.get_json() == {"received": {"title": "Shopping List", "body": "milk, bread"}} \ No newline at end of file