BUG/MEDIUM: mux-h2: Xfer rxbuf to the upper layer when creating a front stream

Just like the H1 muliplexer, when a new frontend H2 stream is created, the
rxbuf is xferred to the stream at the upper layer.

Originally, it is not a bug fix, but just an api standardization. And in
fact, it fixes a crash when a h2 stream is aborted after the request parsing
but before the first call to process_stream(). It crashes since the commit
8bebd2fe5 ("MEDIUM: http-ana: Don't process partial or empty request
anymore"). It is now totally unexpected to have an HTTP stream without a
valid request. But here the stream is unable to get the request because the
client connection was aborted. Passing it during the stream creation fixes
the bug. But the true problem is that the stream-interfaces are still
relying on the connection state while only the muxes should do so.

This fix is specific for 2.4. No backport needed.
This commit is contained in:
Christopher Faulet 2020-12-15 16:56:50 +01:00
parent 8f100427c4
commit 7d013e796c

View File

@ -1458,9 +1458,12 @@ static struct h2s *h2s_new(struct h2c *h2c, int id)
}
/* creates a new stream <id> on the h2c connection and returns it, or NULL in
* case of memory allocation error.
* case of memory allocation error. <input> is used as input buffer for the new
* stream. On success, it is transferred to the stream and the mux is no longer
* responsible of it. On error, <input> is unchanged, thus the mux must still
* take care of it.
*/
static struct h2s *h2c_frt_stream_new(struct h2c *h2c, int id)
static struct h2s *h2c_frt_stream_new(struct h2c *h2c, int id, struct buffer *input)
{
struct session *sess = h2c->conn->owner;
struct conn_stream *cs;
@ -1484,7 +1487,7 @@ static struct h2s *h2c_frt_stream_new(struct h2c *h2c, int id)
cs->ctx = h2s;
h2c->nb_cs++;
if (stream_create_from_cs(cs, &BUF_NULL) < 0)
if (stream_create_from_cs(cs, input) < 0)
goto out_free_cs;
/* We want the accept date presented to the next stream to be the one
@ -2663,15 +2666,17 @@ static struct h2s *h2c_frt_handle_headers(struct h2c *h2c, struct h2s *h2s)
/* Note: we don't emit any other logs below because ff we return
* positively from h2c_frt_stream_new(), the stream will report the error,
* and if we return in error, h2c_frt_stream_new() will emit the error.
*
* Xfer the rxbuf to the stream. On success, the new stream owns the
* rxbuf. On error, it is released here.
*/
h2s = h2c_frt_stream_new(h2c, h2c->dsi);
h2s = h2c_frt_stream_new(h2c, h2c->dsi, &rxbuf);
if (!h2s) {
h2s = (struct h2s*)h2_refused_stream;
goto send_rst;
}
h2s->st = H2_SS_OPEN;
h2s->rxbuf = rxbuf;
h2s->flags |= flags;
h2s->body_len = body_len;