]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: stream: Stop waiting for more data if SI is blocked on RXBLK_ROOM
authorChristopher Faulet <cfaulet@haproxy.com>
Thu, 23 Sep 2021 12:46:32 +0000 (14:46 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Thu, 23 Sep 2021 14:18:07 +0000 (16:18 +0200)
If the stream-interface is waiting for more buffer room to store incoming
data, it is important at the stream level to stop to wait for more data to
continue. Thanks to the previous patch ("BUG/MEDIUM: stream-int: Notify
stream that the mux wants more room to xfer data"), the stream is woken up
when this happens. In this patch, we take care to interrupt the
corresponding tcp-content ruleset or to stop waiting for the HTTP message
payload.

To ease detection of the state, si_rx_blocked_room() helper function has
been added. It returns non-zero if the stream interface's Rx path is blocked
because of lack of room in the input buffer.

This patch is part of a series related to the issue #1362. It should be
backported as ar as 2.0, probably with some adaptations. So be careful
during backports.

include/haproxy/stream_interface.h
src/http_ana.c
src/tcp_rules.c

index 9492e82793c5b4e24f3643a29cf428f24e7d7b83..a1f67c2dcb8e205efb59e4f06b97c46c47e17406 100644 (file)
@@ -242,6 +242,15 @@ static inline int si_rx_blocked(const struct stream_interface *si)
        return !!(si->flags & SI_FL_RXBLK_ANY);
 }
 
+
+/* Returns non-zero if the stream interface's Rx path is blocked because of lack
+ * of room in the input buffer.
+ */
+static inline int si_rx_blocked_room(const struct stream_interface *si)
+{
+       return !!(si->flags & SI_FL_RXBLK_ROOM);
+}
+
 /* Returns non-zero if the stream interface's endpoint is ready to receive */
 static inline int si_rx_endp_ready(const struct stream_interface *si)
 {
index 3480e962037ddaef27aec31fd9aa84bc22f4c175..7d9abdbbc87423db120ac5190efaa4036a1227e7 100644 (file)
@@ -4060,8 +4060,10 @@ enum rule_result http_wait_for_msg_body(struct stream *s, struct channel *chn,
        /* Now we're in HTTP_MSG_DATA. We just need to know if all data have
         * been received or if the buffer is full.
         */
-       if ((htx->flags & HTX_FL_EOM) || htx_get_tail_type(htx) > HTX_BLK_DATA ||
-           channel_htx_full(chn, htx, global.tune.maxrewrite))
+       if ((htx->flags & HTX_FL_EOM) ||
+           htx_get_tail_type(htx) > HTX_BLK_DATA ||
+           channel_htx_full(chn, htx, global.tune.maxrewrite) ||
+           si_rx_blocked_room(chn_prod(chn)))
                goto end;
 
        if (bytes) {
index bbd5820b4c0e30351c0206331a394f031f6ed50c..72b1cd37c36485e97aee5cc30efe64caa74e07db 100644 (file)
@@ -113,6 +113,7 @@ int tcp_inspect_request(struct stream *s, struct channel *req, int an_bit)
         */
 
        if ((req->flags & CF_SHUTR) || channel_full(req, global.tune.maxrewrite) ||
+           si_rx_blocked_room(chn_prod(req)) ||
            !s->be->tcp_req.inspect_delay || tick_is_expired(s->rules_exp, now_ms))
                partial = SMP_OPT_FINAL;
        else
@@ -268,6 +269,7 @@ int tcp_inspect_response(struct stream *s, struct channel *rep, int an_bit)
         * - if one rule returns KO, then return KO
         */
        if ((rep->flags & CF_SHUTR) || channel_full(rep, global.tune.maxrewrite) ||
+           si_rx_blocked_room(chn_prod(rep)) ||
            !s->be->tcp_rep.inspect_delay || tick_is_expired(s->rules_exp, now_ms))
                partial = SMP_OPT_FINAL;
        else