On Fri, Dec 29, 2017 at 03:42:30PM +0100, Willy Tarreau wrote:
> OK I managed to reproduce it with nghttp using --expect-continue to
> force it to leave a pause before sending the data. And indeed there
> the data are immediately followed by a shutdown. Getting closer...

So here's what I found : when dealing with request forwarding, we used
to let the close migrate from the client to the server with the last
block. And this happens only once we switch to fast forwarding, which
means that the last block from the request didn't fit in the buffer.
Thus it would randomly impact large uploads (though timing would often
protect them) and almost always impact small ones if sent in two parts
as we could produce.

The attached patch fixes it for me. Could you please give it a try ?

Thanks,
Willy
diff --git a/src/proto_http.c b/src/proto_http.c
index f585dee..64bd410 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -4963,8 +4963,13 @@ int http_request_forward_body(struct stream *s, struct 
channel *req, int an_bit)
 
        /* When TE: chunked is used, we need to get there again to parse 
remaining
         * chunks even if the client has closed, so we don't want to set 
CF_DONTCLOSE.
+        * And when content-length is used, we never want to let the possible
+        * shutdown be forwarded to the other side, as the state machine will
+        * take care of it once the client responds. It's also important to
+        * prevent TIME_WAITs from accumulating on the backend side, and for
+        * HTTP/2 where the last frame comes with a shutdown.
         */
-       if (msg->flags & HTTP_MSGF_TE_CHNK)
+       if (msg->flags & (HTTP_MSGF_TE_CHNK|HTTP_MSGF_CNT_LEN))
                channel_dont_close(req);
 
        /* We know that more data are expected, but we couldn't send more that

Reply via email to