BUG/MEDIUM: channel: don't allow to overwrite the reserve until connected

Commit 9c06ee4 ("BUG/MEDIUM: channel: don't schedule data in transit for
leaving until connected") took care of an issue involving POST in conjunction
with http-send-name-header, where we absolutely never want to touch the
reserve until we're sure not to touch the buffer contents anymore, which
is indicated by the output stream-interface being connected.

But channel_may_recv() was not equipped with such a test, so in some
situations it might decide that it is possible to poll for reads, and
later channel_recv_limit() will decide it's not possible to read,
causing a loop. So we must add a similar test there.

Since the fix above was backported to 1.6 and 1.5, this fix must as well.
This commit is contained in:
Willy Tarreau 2016-04-20 20:09:22 +02:00
parent c3fe5330be
commit 4b46a3e8cc

View File

@ -165,7 +165,9 @@ static inline int channel_may_send(const struct channel *chn)
* end of transfer is close to happen. Note that both ->buf->o and ->to_forward
* are considered as available since they're supposed to leave the buffer. The
* test is optimized to avoid as many operations as possible for the fast case
* and to be used as an "if" condition.
* and to be used as an "if" condition. Just like channel_recv_limit(), we
* never allow to overwrite the reserve until the output stream interface is
* connected, otherwise we could spin on a POST with http-send-name-header.
*/
static inline int channel_may_recv(const struct channel *chn)
{
@ -179,6 +181,9 @@ static inline int channel_may_recv(const struct channel *chn)
if (!rem)
return 0; /* buffer already full */
if (rem <= global.tune.maxrewrite && !channel_may_send(chn))
return 0;
/* now we know there's some room left, verify if we're touching
* the reserve with some permanent input data.
*/