The ASGI specification current states that,
The protocol server must not start sending the response to the client until it has received at least one Response Body event.
Hypercorn interprets this such that it waits to a response body event is received before it sends the first response line and headers, and as I understand it, Daphne does the same. Uvicorn on the other hand sends the response (line and headers) straight away.
I think this part of the specification follows from the WSGI specification,
The start_response callable must not actually transmit the response headers. Instead, it must store them for the server or gateway to transmit only after the first iteration of the application return value that yields a non-empty string, or upon the application's first invocation of the write() callable. In other words, response headers must not be sent until there is actual body data available, or until the application's returned iterable is exhausted. (The only possible exception to this rule is if the response headers explicitly include a Content-Length of zero.)
with the justification for ASGI likely also following the WSGI justification,
This delaying of response header transmission is to ensure that buffered and asynchronous applications can replace their originally intended output with error output, up until the last possible moment. For example, the application may need to change the response status from "200 OK" to "500 Internal Error", if an error occurs while the body is being generated within an application buffer.
I've been asked on Hypercorn if this part of the specification is necessary, and I'm not convinced it is. I think the WSGI justification isn't that strong in that it only supports a rare case of failure between response.start and response.body. Whereas without this feature all failures post response.start would be treated the same way. It also seems that Uvicorn works fine without this.
The ASGI specification current states that,
Hypercorn interprets this such that it waits to a response body event is received before it sends the first response line and headers, and as I understand it, Daphne does the same. Uvicorn on the other hand sends the response (line and headers) straight away.
I think this part of the specification follows from the WSGI specification,
with the justification for ASGI likely also following the WSGI justification,
I've been asked on Hypercorn if this part of the specification is necessary, and I'm not convinced it is. I think the WSGI justification isn't that strong in that it only supports a rare case of failure between response.start and response.body. Whereas without this feature all failures post response.start would be treated the same way. It also seems that Uvicorn works fine without this.