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.
(cherry picked from commit cfba9d6eaa713b5f5b7244af824f106478214851)
Signed-off-by: Willy Tarreau <w@1wt.eu>
diff --git a/src/mux_h2.c b/src/mux_h2.c
index a02e138..b133288 100644
--- a/src/mux_h2.c
+++ b/src/mux_h2.c
@@ -3281,6 +3281,14 @@
*/
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)
@@ -3314,11 +3322,10 @@
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)) &&