From: Christopher Faulet Date: Wed, 4 Nov 2026 11:01:27 +0000 (+0100) Subject: BUG/MEDIUM: spoe: stop waiting on a dead producer channel X-Git-Url: https://git.kaiwu.me/$%7BISSUES%7D/static/gitweb.js?a=commitdiff_plain;h=cff177fb6ea07e952ecb7327bda768b447b499e1;p=haproxy.git BUG/MEDIUM: spoe: stop waiting on a dead producer channel spoe_process_event() interrupts a pending event processing when the frontend connector reports an error or an early close: there is no point waiting for an agent reply if the stream is being torn down from the client side. The check was only made on the frontend connector. With an event bound to the response channel (on-http-response), a server error reported while the processing is pending leaves the SPOE context in SENDING_MSGS/ WAITING_ACK with the processing timeout armed on res->analyse_exp, and nothing can wake it up anymore. Test the error on the producer of the channel the event is bound to: scb in addition to scf for response-side events, the scf checks remaining valid whatever the direction. For the response side, only SC_FL_ERROR is relevant: an early server close with "option abortonclose" is a request-side semantic which is already handled on the request path. The context then concludes with the INTERRUPT error, which lets the response analyser proceed and deliver whatever response was already received. This is the SPOE part of github issue #3559: with a filter engine bound to on-http-response, an H2 backend answering early and resetting its stream while the request body is still being uploaded used to leave the stream spinning in process_stream() until the watchdog killed the worker. The send-spoe-group action is covered by the http-ana fix, as it is called from the http-response rule engine. This patch should be backported as far as 3.2. --- diff --git a/src/flt_spoe.c b/src/flt_spoe.c index d9fe38635..59d2e9270 100644 --- a/src/flt_spoe.c +++ b/src/flt_spoe.c @@ -1171,7 +1171,8 @@ static int spoe_process_event(struct stream *s, struct spoe_context *ctx, agent->counters.nb_errors, agent->counters.nb_processed); } else if (ret == 0) { - if ((s->scf->flags & SC_FL_ERROR) || + if (((dir == SMP_OPT_DIR_RES) && (s->scb->flags & SC_FL_ERROR)) || + (s->scf->flags & SC_FL_ERROR) || ((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);