&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) {
/* 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 */