diff --git a/src/proxy.c b/src/proxy.c index 335bbafe0..c9a038413 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -2176,23 +2176,27 @@ int stream_set_backend(struct stream *s, struct proxy *be) &s->si[0].wait_event); if (conn_upgrade_mux_fe(conn, cs, &s->req.buf, ist(""), PROTO_MODE_HTTP) == -1) return 0; + + s->req.flags &= ~(CF_READ_PARTIAL|CF_AUTO_CONNECT); + s->req.total = 0; + s->flags |= SF_IGNORE; if (strcmp(conn->mux->name, "H2") == 0) { /* For HTTP/2, destroy the conn_stream, - * disable logging, and pretend that we - * failed, to that the stream is - * silently destroyed. The new mux - * will create new streams. + * disable logging, and abort the stream + * process. Thus it will be silently + * destroyed. The new mux will create + * new streams. */ cs_free(cs); si_detach_endpoint(&s->si[0]); s->logs.logwait = 0; s->logs.level = 0; - s->flags |= SF_IGNORE; - return 0; + channel_abort(&s->req); + channel_abort(&s->res); + s->req.analysers &= AN_REQ_FLT_END; + s->req.analyse_exp = TICK_ETERNITY; + return 1; } - s->req.flags &= ~(CF_READ_PARTIAL|CF_AUTO_CONNECT); - s->req.total = 0; - s->flags |= SF_IGNORE; } } else if (IS_HTX_STRM(s) && be->mode != PR_MODE_HTTP) { diff --git a/src/stream.c b/src/stream.c index b0c2bab37..9ef292d92 100644 --- a/src/stream.c +++ b/src/stream.c @@ -1109,11 +1109,21 @@ static int process_switching_rules(struct stream *s, struct channel *req, int an /* To ensure correct connection accounting on the backend, we * have to assign one if it was not set (eg: a listen). This * measure also takes care of correctly setting the default - * backend if any. + * backend if any. Don't do anything if an upgrade is already in + * progress. */ - if (!(s->flags & SF_BE_ASSIGNED)) + if (!(s->flags & (SF_BE_ASSIGNED|SF_IGNORE))) if (!stream_set_backend(s, fe->defbe.be ? fe->defbe.be : s->be)) goto sw_failed; + + /* No backend assigned but no error reported. It happens when a + * TCP stream is upgraded to HTTP/2. + */ + if ((s->flags & (SF_BE_ASSIGNED|SF_IGNORE)) == SF_IGNORE) { + DBG_TRACE_DEVEL("leaving with no backend because of a destructive upgrade", STRM_EV_STRM_ANA, s); + return 0; + } + } /* we don't want to run the TCP or HTTP filters again if the backend has not changed */