BUG/MEDIUM: mux-h1: Don't release H1 stream upgraded from TCP on error

When an error occurred during the request parsing, the H1 multiplexer is
responsible to sent a response to the client and to release the H1 stream
and the H1 connection. In HTTP mode, it is not an issue because at this
stage the H1 connection is in embryonic state. Thus it can be released
immediately.

However, it is a problem if the connection was first upgraded from a TCP
connection. In this case, a stream-connector is attached. The H1 stream is
not orphan. Thus it must not be released at this stage. It must be detached
first. Otherwise a BUG_ON() is triggered in h1s_destroy().

So now, the H1S is destroyed on early errors but only if the H1C is in
embryonic state.

This patch may be related to #1966. It must be backported to 2.7.
This commit is contained in:
Christopher Faulet 2022-12-15 09:22:35 +01:00
parent f5994fc692
commit da93802ffc
2 changed files with 9 additions and 1 deletions

View File

@ -155,6 +155,13 @@ client c_err3 -connect ${h1_err3h1_sock} {
expect_close expect_close
} -run } -run
# TCP > HTTP upgrade with a parsing error
client c_err4 -connect ${h1_fe2h1_sock} {
send "GET / BAD-VERSION\r\n\r\n"
rxresp
expect resp.status == 400
} -run
# To be sure no other request was received by the server # To be sure no other request was received by the server
client c_end -connect ${s1_sock} { client c_end -connect ${s1_sock} {
txreq txreq

View File

@ -2629,7 +2629,8 @@ static int h1_send_error(struct h1c *h1c)
} }
} }
if (h1c->h1s) { if (h1c->state == H1_CS_EMBRYONIC) {
BUG_ON(h1c->h1s == NULL || h1s_sc(h1c->h1s) == NULL);
TRACE_DEVEL("Abort embryonic H1S", H1_EV_H1C_ERR, h1c->conn, h1c->h1s); TRACE_DEVEL("Abort embryonic H1S", H1_EV_H1C_ERR, h1c->conn, h1c->h1s);
h1s_destroy(h1c->h1s); h1s_destroy(h1c->h1s);
} }