]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: http-ana: Report 502 from req analyzer only during rsp forwarding
authorChristopher Faulet <cfaulet@haproxy.com>
Tue, 15 Apr 2025 06:18:48 +0000 (08:18 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Tue, 15 Apr 2025 14:28:15 +0000 (16:28 +0200)
A server abort must be handled by the request analyzers only when the
response forwarding was already started. Otherwise, it it the responsability
of the response analyzer to detect this event. L7-retires and conditions to
decide to silently close a client conneciotn are handled by this analyzer.

Because a reused server connections closed too early could be detected at
the wrong place, it was possible to get a 502/SH instead of a silent close,
preventing the client to safely retries its request.

Thanks to this patch, we are able to silently close the client connection in
this case and eventually to perform a L7 retry.

This patch must be backported as far as 2.8.

src/http_ana.c

index 68db27f56ab01273622094bfeb16d0c6c1e97cca..43466df6cfd2f13d37533b6e93a6fae7a5b38e12 100644 (file)
@@ -1020,9 +1020,10 @@ int http_request_forward_body(struct stream *s, struct channel *req, int an_bit)
 
        if ((s->scb->flags & SC_FL_SHUT_DONE) && co_data(req)) {
                /* request errors are most likely due to the server aborting the
-                * transfer.Bit handle server aborts only if there is no
-                * response. Otherwise, let a change to forward the response
-                * first.
+                * transfer. But handle server aborts only if the response was
+                * not received yet. Otherwise, let the response analyzer the
+                * responsability to handle the error. It is especially
+                * important to properly handle L7-retries but also K/A silent close.
                 */
                if (txn->rsp.msg_state >= HTTP_MSG_BODY && htx_is_empty(htxbuf(&s->res.buf)))
                        goto return_srv_abort;
@@ -1063,10 +1064,12 @@ int http_request_forward_body(struct stream *s, struct channel *req, int an_bit)
  waiting:
        /* waiting for the last bits to leave the buffer */
        if (s->scb->flags & SC_FL_SHUT_DONE) {
-               /* Handle server aborts only if there is no response. Otherwise,
-                * let a change to forward the response first.
+               /* Handle server aborts only if the response was not received
+                * yet. Otherwise, let the response analyzer the responsability
+                * to handle the error. It is especially important to properly
+                * handle L7-retries but also K/A silent close.
                 */
-               if (htx_is_empty(htxbuf(&s->res.buf)))
+               if (txn->rsp.msg_state >= HTTP_MSG_BODY && htx_is_empty(htxbuf(&s->res.buf)))
                        goto return_srv_abort;
        }