In a recent thread on the uwsgi mailing list, I began suspecting that
nginx will not honor an upstream’s Content-Length header. i.e., if an
upstream mentions a Content-Length of 1,000 bytes, but the connection is
broken after 500 bytes, nginx will still happily serve this entity with
200 OK status.
This may be a known bug in nginx, I wanted to be certain I indeed
it correctly and raise the attention to it on the nginx mailing list -
because I think this is a very serious bug with potentially disastrous
consequences, as I describe below.
I was able to confirm this both for uwsgi_pass and proxy_pass; if the
upstream sets a Content-Length and then breaks the connection before
length was achieved, nginx will pass this onwards to the client.
Furthermore, since the upstream protocol is HTTP 1.0 but the
protocl is HTTP 1.1 (with keepalive), the request will simply not
because the client can’t tell that the server has nothing more to send
nginx will not break the connection, despite the fact its connection
the upstream was broken and there’s no chance this request will ever be
Things get far worse with gzip compression on - nginx will remove the
Content-Length header sent by the client and replace it with chunked
encoding - /incorrect chunked encoding/, that will make the client
it has the full entity, even though it has only a part of this.
Think about this with regard to caching, ETags and transparent proxy
- if something like this happens to a cachable entity, especially one
an ETag, especially if a large ISP’s transparent proxy intercepts the
request - you might end up serving an incorrect representation of the
for a very long time and for many thousands of requests (!).
Anyhow, I think the only sane resolution is that nginx will honor
Content-Length (and chunked encoding, if and when nginx will support
and intentionally close the downstream connection prematurely in case
upstream connection is closed before the end of the Content-Length or
last chunk is received.
I suspect the recent work in nginx 1.1.4 for
ngx_http_upstream_keepalivecould be relevant here, but not sure,
didn’t read the code.
I’ll be happy to hear your thoughts or provide further data.