<div dir="ltr">Hi,<div><br></div><div>In a recent thread on the uwsgi mailing list[1], 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 a 200 OK status.</div>
<div><br></div><div>This may be a known bug in nginx, I wanted to be certain I indeed understand 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.</div>
<div><br></div><div>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 that length was achieved, nginx will pass this onwards to the client. Furthermore, since the upstream protocol is HTTP 1.0 but the nginx-client protocl is HTTP 1.1 (with keepalive), the request will simply not terminate, because the client can't tell that the server has nothing more to send and nginx will not break the connection, despite the fact its connection with the upstream was broken and there's no chance this request will ever be fulfilled.</div>
<div><br></div><div>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 believe it has the full entity, even though it has only a part of this.</div>
<div><br></div><div>Think about this with regard to caching, ETags and transparent proxy caching - if something like this happens to a cachable entity, especially one with an ETag, especially if a large ISP's transparent proxy intercepts the request - you might end up serving an incorrect representation of the entity for a very long time and for many thousands of requests (!).</div>
<div><font face="arial, helvetica, sans-serif"><span style="white-space:pre-wrap"><br></span></font></div><div><font face="arial, helvetica, sans-serif"><span style="white-space:pre-wrap">Anyhow, I think the only sane resolution is that nginx will honor upstream Content-Length (and chunked encoding, if and when nginx will support it), and intentionally close the downstream connection prematurely in case the upstream connection is closed before the end of the Content-Length or the last chunk is received.</span></font></div>
<div><font face="arial, helvetica, sans-serif"><span style="white-space:pre-wrap"><br></span></font></div><div><font face="arial, helvetica, sans-serif"><span style="white-space:pre-wrap"><span class="Apple-style-span" style="font-family: arial; white-space: normal; ">I suspect the recent work in nginx 1.1.4 for <span style="white-space: pre-wrap; "><font face="'courier new', monospace">ngx_http_upstream_keepalive</font></span><span style="white-space: pre-wrap; "><font face="arial, helvetica, sans-serif"> could be relevant here, but not sure, didn't read the code.</font></span></span></span></font></div>
<div><font face="arial, helvetica, sans-serif"><span style="white-space:pre-wrap"><span class="Apple-style-span" style="font-family: arial; white-space: normal; "><span style="white-space: pre-wrap; "><font face="arial, helvetica, sans-serif"><br>
</font></span></span></span></font></div><div><font face="arial, helvetica, sans-serif"><span style="white-space:pre-wrap"><span class="Apple-style-span" style="font-family: arial; white-space: normal; "><span style="white-space: pre-wrap; "><font face="arial, helvetica, sans-serif">I'll be happy to hear your thoughts or provide further data.</font></span></span></span></font></div>
<div><font face="arial, helvetica, sans-serif"><span style="white-space:pre-wrap"><span class="Apple-style-span" style="font-family: arial; white-space: normal; "><span style="white-space: pre-wrap; "><font face="arial, helvetica, sans-serif"><br>
</font></span></span></span></font></div><div><font face="arial, helvetica, sans-serif"><span style="white-space:pre-wrap"><span class="Apple-style-span" style="font-family: arial; white-space: normal; "><span style="white-space: pre-wrap; "><font face="arial, helvetica, sans-serif"> - Yaniv</font></span></span></span></font></div>
<div><br></div><div>1: <a href="http://comments.gmane.org/gmane.comp.python.wsgi.uwsgi.general/2061" target="_blank">http://comments.gmane.org/gmane.comp.python.wsgi.uwsgi.general/2061</a></div></div>