BUG/MEDIUM: h1: make the Connection/Upgrade headers cleanup idempotent
The H1 parser rewrites the Connection header value in place to remove the
"close" and "keep-alive" tokens (H1_MF_CLEAN_CONN_HDR, always set by the H1
mux), and the Upgrade header value to remove the "h2c" and "h2" tokens. The
kept tokens are moved to the beginning of the value and the value's length
is reduced, but the original bytes beyond the new length are left untouched
in the input buffer.
However the parser is designed to restart from the beginning of the message
once an incomplete one is completed, and it relies on in-place modifications
being idempotent. When the headers block is received in several parts and
one of these headers was already processed in a first pass, the second pass
parses the rewritten value followed by the remains of the original one.
To fix the issue, the bytes freed at the end of the rewritten value are now
replaced with spaces so that parsing the same area again gives the same
value (trailing spaces are trimmed). And since the removed "close" and
"keep-alive" tokens are not there anymore on the second pass, the
H1_MF_CONN_CLO and H1_MF_CONN_KAL flags are now preserved when the parsing
is restarted, and when the parser is reset after an output full condition.
The Connection header issue exists since commit
a51ebb7f5 ("MEDIUM: h1: Add
an option to sanitize connection headers during parsing") in 2.0, the
Upgrade one since commit
8dd49dfab ("BUG/MEDIUM: h1: Skip all h2c values
from Upgrade headers during parsing") in 3.4 (and its backports). This must
be backported to all stable versions.