There is an issue when I try to send PUT/POST request with body to Django ASGI app.
I’m not entirely sure of the origin of issue but I noticed it happens only since Django version 5.0 and NGINX Unit as ASGI server.
AssertionError: Invalid ASGI message after request body: http.request
If I use Django version less than 5 it works perfectly fine. Also if in newer version of Django I override ASGIHandler with the one used before version 5 it works perfectly fine. The main difference between those two is that the newer one listens to http.disconnect
I submitted an issue ticket on Django which was dismissed and also issue ticket on Unit.
Further, if I use granian or uvicorn as ASGI server there is no issue. So I suspect that there is something wrong with both updated Django ASGIHandler and Unit’s ASGI implementation.
I also created a demo project in public repo to easily reproduce this behavior.
If you pin django to <5.0 it will work, if you use >=5.0 it will fail.
Entire traceback is available in NGINX Unit ticket with also server debug log.
As a final test, I’d suggest trying it with Daphne. If your project works with Daphne, then I’d agree that this is a problem with Unit’s ASGI implementation.
(While not officially identified as such, I’ve always informally considered Daphne to be the reference implementation for ASGI, since the primary author of the ASGI spec was also the primary developer of Daphne.)
Thank you for this suggestion. I tried with Daphne and it seems to work ok.
I guess then I see this as three different possibilities, listed in what I think the order of probability is:
- The Unit’s implementation of ASGI isn’t fully compliant with the specification.
- The ASGI specification has a gap such that all four implementations listed here are valid.
- The implementations of Daphne, uvicorn and granian are all not fully compliant with the ASGI spec.
Ultimately, I think we need to wait for someone familiar with Unit to weigh in.
1 Like
I just updated my demo project to easily test against uvicorn, daphne, granian and unit. And it seems like only unit is problematic one.
You are welcome to pull this and propose whatever you think might be a solution.
This looks like Unit isn’t correctly handling the more_body
key of the http.request
event.
https://asgi.readthedocs.io/en/latest/specs/www.html#request-receive-event
After an http.request
event where more_body
is False
the only permitted event is http.disconnect
. Hence the assertion.
1 Like
@carltongibson Would you maybe be willing to take a look at the discussion: Django ASGI: Invalid ASGI message after request body: http.request · Issue #1561 · nginx/unit · GitHub
The lifespan unsupported is normal behavior, but maybe you can give more insight to Unit devs.
I noticed if I comment out assertion line inside listen_for_disconnect
method on ASGIHandler
it works ok. But I also noticed comment # This should never happen.
on the line before.
@codedoga Sorry, I don’t have capacity to engage in the Nginx Unit issue.
1 Like