When Gunicorn receives a request that's missing the second CRLF in the final chunk, it doesn't reject the request.
To see this for yourself,
- Start a Gunicorn server, such as this one:
python3 -m gunicorn --worker-class=gevent --workers=1 --worker-connections=1000 --bind 0.0.0.0:80 server:app
- Send it a request that's missing the final chunk's second CRLF
printf 'POST / HTTP/1.1\r\nHost: a\r\nTransfer-Encoding: chunked\r\n\r\n0\r\n' \
| ncat localhost 80
- Observe that it still responds:
HTTP/1.1 200 OK
Server: gunicorn
Date: Sat, 12 Apr 2025 22:57:45 GMT
Connection: keep-alive
Content-type: application/json
Content-Length: 145
{"headers":[["SE9TVA==","YQ=="],["VFJBTlNGRVJfRU5DT0RJTkc=","Y2h1bmtlZA=="]],"body":"","version":"SFRUUC8xLjE=","uri":"Lw==","method":"UE9TVA=="}
When Gunicorn receives a request that's missing the second CRLF in the final chunk, it doesn't reject the request.
To see this for yourself,