]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: http-ana: Only consider client abort for abortonclose
authorChristopher Faulet <cfaulet@haproxy.com>
Fri, 27 Mar 2026 10:18:39 +0000 (11:18 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Fri, 27 Mar 2026 10:18:40 +0000 (11:18 +0100)
When abortonclose option is enabled (by default since 3.3), the HTTP rules
can no longer yield if the client aborts. However, stream aborts were also
considered. So it was possible to interrupt yielding rules, especially on
the response processing, while the client was still waiting for the
response.

So now, when abortonclose option is enabled, we now take care to only
consider client aborts to prevent HTTP rules to yield.

Many thanks to @DirkyJerky for his detailed analysis.

This patch should fix the issue #3306. It should be backported as far as
2.8.

src/flt_spoe.c
src/http_ana.c

index 39a56b11e8d8cd9c2fcdb301aae00c670998ff9d..48bce2507725ac959213792f7e474f9ac1da9df5 100644 (file)
@@ -1114,7 +1114,7 @@ static int spoe_process_event(struct stream *s, struct spoe_context *ctx,
        }
        else if (ret == 0) {
                if ((s->scf->flags & SC_FL_ERROR) ||
-                   ((s->scf->flags & (SC_FL_EOS|SC_FL_ABRT_DONE)) && proxy_abrt_close_def(s->be, 1))) {
+                   ((s->scf->flags & SC_FL_EOS) && proxy_abrt_close_def(s->be, 1))) {
                        ctx->status_code = SPOE_CTX_ERR_INTERRUPT;
                        spoe_stop_processing(agent, ctx);
                        spoe_handle_processing_error(s, agent, ctx, dir);
index 80726e9f6c5d879752f0e05797edaffb15bd9417..8a00d5b794d0d3ca64374b9afd3332e9225d62df 100644 (file)
@@ -2828,8 +2828,7 @@ static enum rule_result http_req_get_intercept_rule(struct proxy *px, struct lis
        int act_opts = 0;
 
        if ((s->scf->flags & SC_FL_ERROR) ||
-           ((s->scf->flags & (SC_FL_EOS|SC_FL_ABRT_DONE)) &&
-            proxy_abrt_close_def(px, 1)))
+           ((s->scf->flags & SC_FL_EOS) && proxy_abrt_close_def(px, 1)))
                act_opts |= ACT_OPT_FINAL | ACT_OPT_FINAL_EARLY;
 
        /* If "the current_rule_list" match the executed rule list, we are in
@@ -3020,8 +3019,7 @@ static enum rule_result http_res_get_intercept_rule(struct proxy *px, struct lis
        if (final)
                act_opts |= ACT_OPT_FINAL;
        if ((s->scf->flags & SC_FL_ERROR) ||
-           ((s->scf->flags & (SC_FL_EOS|SC_FL_ABRT_DONE)) &&
-            proxy_abrt_close_def(px, 1)))
+           ((s->scf->flags & SC_FL_EOS) && proxy_abrt_close_def(px, 1)))
                act_opts |= ACT_OPT_FINAL | ACT_OPT_FINAL_EARLY;
 
        /* If "the current_rule_list" match the executed rule list, we are in
@@ -4356,8 +4354,7 @@ enum rule_result http_wait_for_msg_body(struct stream *s, struct channel *chn,
        /* we get here if we need to wait for more data */
 
        if ((s->scf->flags & SC_FL_ERROR) ||
-           ((s->scf->flags & (SC_FL_EOS|SC_FL_ABRT_DONE)) &&
-            proxy_abrt_close_def(s->be, 1)))
+           ((s->scf->flags & SC_FL_EOS) && proxy_abrt_close_def(s->be, 1)))
                ret = HTTP_RULE_RES_CONT;
        else if (!(chn_prod(chn)->flags & (SC_FL_ERROR|SC_FL_EOS|SC_FL_ABRT_DONE))) {
                if (!tick_isset(chn->analyse_exp))