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