From: Willy Tarreau Date: Tue, 10 Jan 2023 13:50:44 +0000 (+0100) Subject: BUG/MINOR: http-ana: make set-status also update txn->status X-Git-Tag: v2.8-dev2~37 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=640e253698b1016f115552d1d5bbb81e5263377d;p=thirdparty%2Fhaproxy.git BUG/MINOR: http-ana: make set-status also update txn->status Patrick Hemmer reported an interesting case where the status present in the logs doesn't reflect what was reported to the user. During analysis we could figure that it was in fact solely caused by the code dealing with the set-status action. Indeed, set-status does update the status in the HTX message itself but not in the HTTP transaction. However, at most places where the status is needed to take a decision, it is retrieved from the transaction, and the logs proceed like this as well, though the "status" sample fetch function does retrieve it from the HTX data. This particularly means that once a set-status has been used to modify the status returned to the user, logs do not match that status, and the response code distribution doesn't match either. However a subsequent rule using the status as a condition will still match because the "status" sample fetch function does also extract the status from the HTX stream. Here's an example that fails: frontend f bind :8001 mode http option httplog log stdout daemon http-after-response set-status 400 This will return a 400 to the client but log a 503 and increment http_rsp_5xx. In the end the root cause is that we need to make txn->status the only authoritative place to get the status, and as such it must be updated by the set-status rule. Ideally "status" should just use txn->status but with the two synchronized this way it's not needed. This should be backported since it addresses some consistency issues between logs and what's observed. The set-status action appeared in 1.9 so all stable versions are eligible. --- diff --git a/src/http_ana.c b/src/http_ana.c index 6949562613..1d9423af48 100644 --- a/src/http_ana.c +++ b/src/http_ana.c @@ -2688,6 +2688,7 @@ int http_res_set_status(unsigned int status, struct ist reason, struct stream *s if (!http_replace_res_status(htx, ist2(trash.area, trash.data), reason)) return -1; + s->txn->status = status; return 0; }