I am trying to implement a country based custom error page dependent of the status code like its shown here Serve Dynamic Custom Error Page - my implementation is based on the scenario where they use
http-response return status 404 errorfiles site1 if { status 404 } { var(txn.host) site1.com }
Little about my setup. I have an F5 load-balancer at the edge which does irule based traffic routing. I have three main services that are served as web services (separate irule for each) - lets call them site.no, site.se and site.fi and a bunch of supportin services which run on separate servers and have internal URLs but are not accessible from the outside and only through one of the main three websites. So for example I have service “subservice A” that can be accessed through the three main web sites (for some the paths are different across the NO,SE,FI realm, others may be identical)
https://site.no/some/path/to/subservices/subserviceA
https://site.se/subservices/subservice/A
https://site.fi/some/alternate/path/to/subservices/subserviceA
As I said the proxying trough the main sites is done on the edge reverse proxy/load balancer. After the previously mentioned lb/reverse proxy I have HAProxy as an ingress controller for a container environment (just a bunch of unorchestrated containers doing header enrichment and such). Sometimes those containers are down and HAProxy can detect them and shows the default 50x errors (I have seen 500, 503, 504). In HAProxy I have separate frontends and backends for each of the three main sites and all of the subservices. Custom error pages for the main sites works with
http-errors site-no {
errorfile 500 /path/to/errorfiles/error-500-NO.http
...
errorfile 504 /path/to/errorfiles/error-504-NO.http
}
http-errors site-se {
errorfile 500 /path/to/errorfiles/error-500-SE.http
...
errorfile 504 /path/to/errorfiles/error-504-SE.http
}
http-errors site-fi {
errorfile 500 /path/to/errorfiles/error-500-FI.http
...
errorfile 504 /path/to/errorfiles/error-504-FI.http
}
frontend main-site-no {
...
errorfiles site-no
...
}
frontend main-site-se {
...
errorfiles site-se
...
}
frontend main-site-fi {
...
errorfiles site-fi
...
}
But now with the subservice, as it is pan-NO,SE,FI I have to display the error based on status code and the header Host value - this is where the linked tutorial comes in. I did:
frontend sub-service-A {
...
http-request set-var(txn.host) req.hdr(host)
http-response return status 500 errorfiles site-no if { status 500 } { var(txn.host) site.no }
...
http-response return status 504 errorfiles site-no if { status 504 } { var(txn.host) site.no }
http-response return status 500 errorfiles site-se if { status 500 } { var(txn.host) site.se }
...
http-response return status 504 errorfiles site-se if { status 504 } { var(txn.host) site.se }
http-response return status 500 errorfiles site-fi if { status 500 } { var(txn.host) site.fi }
...
http-response return status 504 errorfiles site-fi if { status 504 } { var(txn.host) site.fi }
...
}
And the problem is that the conditional errors are never triggered - I shut down the subserviceA and HAProxy marks it as DOWN. When I do
curl -I https://haproxy.subserviceA.frontend.ip.address:port -H "Host: site.no"
I get the default error page and not the custom one. The error status is correct - in this case 503 (also I noticed HTTP/2 and HTTP/1.1 show the error status a little differently i.e. HTTP/2 does not show the “Service Unavailable” text - could also be a curl thing)
I have no idea how to debug this. I added logging of req.hdr(host), var(txn.host) and %ST
htt-request capture req.hdr(Host) len 10
log-format "Host: %[capture.req.hdr(0)], Txn.Host: %[var(txn.host)], Status: %ST"
and they all show the pre-conditions to drigger the result:
Host: site.no, Txn.Host: site.no, Status: 503
Does anyone have ideas on how to proceed. I am running HAProxy 2.3.5 on RHEL 8