<div dir="ltr"><div>Hi Maxim,</div><div><br></div><div>thanks for the quick answer and the pointer to the earlier discussion. May I ask if there is there a specific reason for the past discussion not leading to the issue getting resolved, i.e. is this bug on the roadmap somewhere or should I file an issue?</div><div><br></div><div>- Roman</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">On Wed, Nov 19, 2014 at 02:13:41PM +0100, Roman Borschel wrote:<br><br>> Hi,<br>><br>> I'm experiencing an issue whereby nginx and the upstream server get into<br>> disagreement about the state of the HTTP interaction, apparently caused by<br>> nginx not transmitting the complete request body. The scenario is as<br>> follows, using nginx as a reverse proxy with upstream keepalive:<br>><br>> 1. Client sends a POST request to nginx with a Content-Length header and a<br>> relatively large body, i.e. spanning many TCP segments.<br>> 2. Nginx forwards the request line and headers and starts forwarding the<br>> body to the upstream server.<br>> 3. While nginx is still sending, the upstream server responds early with a<br>> 409 based on information in the request headers, without consuming the body.<br>> 4. Nginx eventually stops sending the body, i.e. it does not transmit the<br>> full number of bytes as specified in the Content-Length, presumably because<br>> of the server response.<br>> 5. Nginx reuses the same upstream connection for a different request, in<br>> this case a GET request.<br>> 6. The upstream server does not see this as a new HTTP request, as it is<br>> still awaiting more data according to the Content-Length.<br>><br>> At this point the client who sent the GET request and nginx wait for a<br>> response while the upstream server is waiting for more data until one of<br>> them hits a timeout (whichever has the lowest timeout) which eventually<br>> results in the connection being closed.<br>><br>> According to RFC2616, 8.2.2 [1] if the request contained a Content-Length<br>> and the client (nginx in this case) ceases to transmit the body (due to an<br>> error response) the client (nginx) would have to close the connection,<br>> which does not happen.<br>><br>> I am reasonably certain that the client is always transmitting the full<br>> body as the problem does not occur when the client talks directly to the<br>> upstream server and an otherwise identical request/response pattern (i.e.<br>> an early error response).<br>><br>> Can someone clarify on whether this is expected behaviour / as designed on<br>> behalf of nginx?<br><br>This is a bug, currently keepalive connections cache doesn't know<br>about the fact that nginx stopped sending the body early and the<br>connection shouldn't be cached.  Some earlier discussion and<br>an attempt to fix this can be found in the thread here:<br><br><a href="http://mailman.nginx.org/pipermail/nginx-devel/2012-March/002040.html" target="_blank">http://mailman.nginx.org/pipermail/nginx-devel/2012-March/002040.html</a><br><br>Trivial workaround is to disable use of keepalive connections<br>(actually, this is the default) if your backend behaves this way.<br><br>--<br>Maxim Dounin<br><a href="http://nginx.org/" target="_blank">http://nginx.org/</a><br></blockquote></div>