<div dir="ltr"><div>Cool.  Thanks!<br><br>Initial testing looks like this fixed it.<br><br></div>   --Will<br></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Thu, Nov 21, 2013 at 3:34 AM, Maxim Dounin <span dir="ltr"><<a href="mailto:mdounin@mdounin.ru" target="_blank">mdounin@mdounin.ru</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hello!<br>
<div class="im"><br>
On Wed, Nov 20, 2013 at 06:03:11PM -0800, Will Pugh wrote:<br>
<br>
> Hi folks,<br>
><br>
> We are using Nginx for SSL termination, and then it proxies to an ATS or<br>
> Haproxy server depending on our environment.<br>
><br>
> We're running into a problem where every now and then, Nginx closes a<br>
> connection due to a timeout.  When investigating, it looks like the<br>
> connections that are being timed-out are not being forwarded to the backend<br>
> service.  The scenario when we were able to best reproduce this is one<br>
> where one of our Java client was running about 100 REST requests that were<br>
> fairly similar.  I've attached files that contain both the tcpdump from the<br>
> client side as well as the debug log on the nginx side.<br>
><br>
> I tried comparing a successful and unsuccessful request next to each<br>
> other.  From the client side, it looks like the messages back and forth<br>
> look very consistent.  On the nginx side, the first difference seems to<br>
> happen when reading in the Http Request.  The requests that fail, all seem<br>
> to do a partial read:<br>
<br>
</div>[...]<br>
<br>
I think I see what happens here:<br>
<br>
- Due to a partial read the c->read->ready flag is reset.<br>
<br>
- While processing request headers rest of the body becomes available in a<br>
  socket buffer.<br>
<br>
- The ngx_http_do_read_client_request_body() function calls c->recv(),<br>
  ngx_ssl_recv() in case of SSL, and rest of the data is read from the<br>
  kernel to OpenSSL buffers.  The c->recv() is called with a limited<br>
  buffer space though (in the debug log provided, only 16 bytes - as this<br>
  happens during reading http chunk header), and only part of the data<br>
  becomes available to nginx.<br>
<br>
- As c->read->ready isn't set, ngx_http_do_read_client_request_body() arms<br>
  a read event and returns to the event loop.<br>
<br>
- The socket buffer is empty, so no further events are reported by<br>
  the kernel till timeout.<br>
<br>
Please try the following patch:<br>
<br>
--- a/src/event/ngx_event_openssl.c<br>
+++ b/src/event/ngx_event_openssl.c<br>
@@ -1025,6 +1025,7 @@ ngx_ssl_recv(ngx_connection_t *c, u_char<br>
             size -= n;<br>
<br>
             if (size == 0) {<br>
+                c->read->ready = 1;<br>
                 return bytes;<br>
             }<br>
<br>
@@ -1034,6 +1035,10 @@ ngx_ssl_recv(ngx_connection_t *c, u_char<br>
         }<br>
<br>
         if (bytes) {<br>
+            if (c->ssl->last != NGX_AGAIN) {<br>
+                c->read->ready = 1;<br>
+            }<br>
+<br>
             return bytes;<br>
         }<br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
Maxim Dounin<br>
<a href="http://nginx.org/en/donation.html" target="_blank">http://nginx.org/en/donation.html</a><br>
<br>
_______________________________________________<br>
nginx mailing list<br>
<a href="mailto:nginx@nginx.org">nginx@nginx.org</a><br>
<a href="http://mailman.nginx.org/mailman/listinfo/nginx" target="_blank">http://mailman.nginx.org/mailman/listinfo/nginx</a><br>
</font></span></blockquote></div><br></div>