From: Willy Tarreau Date: Tue, 6 Aug 2019 08:30:58 +0000 (+0200) Subject: BUG/MINOR: mux-h2: do not send REFUSED_STREAM on aborted uploads X-Git-Tag: v2.1-dev2~231 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=cfba9d6eaa713b5f5b7244af824f106478214851;p=thirdparty%2Fhaproxy.git BUG/MINOR: mux-h2: do not send REFUSED_STREAM on aborted uploads If the server decides to close early, we don't want to send a REFUSED_STREAM error but a CANCEL, so that the client doesn't want to retry. The test in h2_do_shutw() was wrong for this as it would handle the HLOC case like the case where nothing had been sent for this stream, which is wrong. Now h2_do_shutw() does nothing in this case and lets h2_do_shutr() decide. Note that this partially undoes f983d00a1 ("BUG/MINOR: mux-h2: make the do_shut{r,w} functions more robust against retries"). This must be backported to 2.0. The patch above was not backported to 1.9 for being too risky there, but if it eventually gets to it, this one will be needed as well. --- diff --git a/src/mux_h2.c b/src/mux_h2.c index 06eb5f4e02..2b34508fba 100644 --- a/src/mux_h2.c +++ b/src/mux_h2.c @@ -3267,6 +3267,14 @@ static void h2_do_shutr(struct h2s *h2s) */ h2s_error(h2s, H2_ERR_REFUSED_STREAM); } + else { + /* a final response was already provided, we don't want this + * stream anymore. This may happen when the server responds + * before the end of an upload and closes quickly (redirect, + * deny, ...) + */ + h2s_error(h2s, H2_ERR_CANCEL); + } if (!(h2s->flags & H2_SF_RST_SENT) && h2s_send_rst_stream(h2c, h2s) <= 0) @@ -3300,11 +3308,10 @@ static void h2_do_shutw(struct h2s *h2s) struct h2c *h2c = h2s->h2c; struct wait_event *sw = &h2s->wait_event; - if (h2s->st == H2_SS_CLOSED) + if (h2s->st == H2_SS_HLOC || h2s->st == H2_SS_CLOSED) goto done; - if (h2s->st != H2_SS_HLOC && h2s->st != H2_SS_ERROR && - (h2s->flags & H2_SF_HEADERS_SENT)) { + if (h2s->st != H2_SS_ERROR && (h2s->flags & H2_SF_HEADERS_SENT)) { /* we can cleanly close using an empty data frame only after headers */ if (!(h2s->flags & (H2_SF_ES_SENT|H2_SF_RST_SENT)) &&