Forum Discussion
Don_22992
Nimbostratus
Apr 02, 2008stubborn 4xx/5xx Error Handler
I am sure this is simple....
I have the following iRule to redirect 4xx & 5xx errors to a page on a backend server. It works great - once I have sucessfully connected to the site once! What am I missing?
when HTTP_REQUEST {
set myhost [HTTP::host]
}
when HTTP_RESPONSE {
if { ([HTTP::status] starts_with "4")} {
HTTP::redirect https://$myhost/images/errors/err_4xx.htm
} elseif { ([HTTP::status] starts_with "5")} {
HTTP::redirect https://$myhost/images/errors/err_5xx.htm
} else {
}
}
7 Replies
- hoolio
Cirrostratus
Can you clarify this? If the pool member responds with a 4xx or 5xx status, the first response still gets through to the client but any subsequent response is redirected? Is that what you mean?
Can you add logging to the rule to check this?when HTTP_REQUEST { set myhost [HTTP::host] } when HTTP_RESPONSE { log local0. "[IP::client_addr]:[TCP::client_port]: Request $myhost generated response status: [HTTP::status]" if { ([HTTP::status] starts_with "4")} { log local0. "[IP::client_addr]:[TCP::client_port]: Redirecting to 4xx.htm" HTTP::redirect https://$myhost/images/errors/err_4xx.htm } elseif { ([HTTP::status] starts_with "5")} { log local0. "[IP::client_addr]:[TCP::client_port]: Redirecting to 5xx.htm" HTTP::redirect https://$myhost/images/errors/err_5xx.htm } else { log local0. "[IP::client_addr]:[TCP::client_port]: Doing nothing" } }
You can check the log output by tailing the ltm log file (tail -f /var/log/ltm).
Aaron - hoolio
Cirrostratus
The rule looks like it's working as it's written. If the server responds with a 4xx or 5xx response, the response is rewritten to a 302 redirect. However, I don't think you actually want to redirect all 4xx and 5xx responses. The browser won't follow the redirect if the redirect is in response to a request for an image. I don't think even if it were possible, that you'd want to redirect the previous request to a page if a single image referenced on the page wasn't found.
Do you know why the application responds with a 500 when requesting the an image referenced by the root page of the site? That might be the first thing to address.
If you wanted to handle this better in an iRule, you might create a list of page types (like .do or /) and then only redirect requests to pages (as opposed to images) if they generate a 4xx or 5xx response from the web app. You could rewrite all other responses 4xx/5xx responses to 200 with no content.
Also, once you enable blocking on your ASM security policy, ASM will automatically take the blocking action for all 5xx responses (except 502).
Can you give this updated rule a try?when RULE_INIT { set ::page_suffixes [list \ .do \ / \ ] } when HTTP_REQUEST { set myhost [HTTP::host] set mypath [HTTP::path] } when HTTP_RESPONSE { log local0. "[IP::client_addr]:[TCP::client_port]: Request $myhost generated response status: [HTTP::status]" if { ([HTTP::status] starts_with "4")} { if { $mypath ends_with $::page_suffixes }{ log local0. "[IP::client_addr]:[TCP::client_port]: request to $mypath generated a [HTTP::status], redirecting to 4xx.htm" HTTP::redirect https://$myhost/images/errors/err_4xx.htm } else { log local0. "[IP::client_addr]:[TCP::client_port]: request to $mypath generated a [HTTP::status], responding with a 200" HTTP::respond 200 } } elseif { ([HTTP::status] starts_with "5")} { if { $mypath ends_with $::page_suffixes }{ log local0. "[IP::client_addr]:[TCP::client_port]: request to $mypath generated a [HTTP::status], redirecting to 5xx.htm" HTTP::redirect https://$myhost/images/errors/err_5xx.htm } else { log local0. "[IP::client_addr]:[TCP::client_port]: request to $mypath generated a [HTTP::status], responding with a 200" HTTP::respond 200 } } else { log local0. "[IP::client_addr]:[TCP::client_port]: Doing nothing" } }
Aaron - Don_22992
Nimbostratus
Aaron,
The resultant behavior of a redirect for an image performs as desired; just may not be very clean. It actually mirrors the processing of an existing process and will be cleaned up in a subsequent revision of the rule/configuration. However, the fact that it was a request for an image at the root is irrelevant. Replacing "/don.jpg" with "/my.jsp", "begin.do", or "/mystuff/index.html" also results in the same behavior.
I do not know WHY or even IF the application responds with a 500 when the root page contains a request for an image.
Lets try with https::/my.domain.com/mystuff/index.html (which most assuredly does not exist and causes a 404 error)
Using this as my request, the following behavior is observed:
1. Bypassing the F5 entirely results in a default 404 error page returned.
2. Removing this iRule results in a default 404 error page returned.
3. WITH the irule, the browser reports page canot be displayed.
This seems to be the heart of the problem.
Don - hoolio
Cirrostratus
Hi Don,
So this was case 2?
Requested "my.domain.com/DJ-Boston.jpg" (modified uri to force a 404 error); Received from browser "Internet Explorer cannot display the webpage":
Apr 3 11:32:28 tmm tmm[1627]: Rule stg-errors : 192.168.16.149:64126: Request my.domain.com generated response status: 404
Apr 3 11:32:28 tmm tmm[1627]: Rule stg-errors : 192.168.16.149:64126: Redirecting to 4xx.htm
Typically, you'd get the page cannot be displayed error when a TCP reset is sent to the client. If this was due to the iRule, I'd expect to see a TCL error. If you grep for TCL error in the ltm log file, do you find any matches (grep -i 'tcl error' /var/log/ltm')?
What version of BIG-IP code are you running? If you remove any ASM-enabled HTTP classes from the VIP, does the client get correctly redirected to 4xx.htm?
Aaron - Don_22992
Nimbostratus
Aaron,
Thanks for your reply.
There were no tcl errors found in the LTM log. However, your last point produced something of interest.
When any ASM-enabled HTTP classes were removed - it works as desired. I have no clue why but hold hope that you will enlighten.
The version I am running is BIG-IP 9.4.3 Build 14.3 Hotfix HF3.
Don - hoolio
Cirrostratus
In previous versions of BIG-IP ASM, you'd need to disable ASM when sending a response from an iRule (Click here). I didn't think that would be necessary in 9.4.2+ with the plugin architecture. Can you open a case with F5 Support asking them to investigate this? If you want to try one more thing, you could explicitly disable the ASM plugin when sending a redirect:when HTTP_REQUEST { set myhost [HTTP::host] } when HTTP_RESPONSE { Initialise a variable to track whether we're redirecting this request set redirect 0 log local0. "[IP::client_addr]:[TCP::client_port]: Request $myhost generated response status: [HTTP::status]" if { ([HTTP::status] starts_with "4")} { log local0. "[IP::client_addr]:[TCP::client_port]: Redirecting to 4xx.htm" HTTP::redirect https://$myhost/images/errors/err_4xx.htm set redirect 1 } elseif { ([HTTP::status] starts_with "5")} { log local0. "[IP::client_addr]:[TCP::client_port]: Redirecting to 5xx.htm" HTTP::redirect https://$myhost/images/errors/err_5xx.htm set redirect 1 } else { log local0. "[IP::client_addr]:[TCP::client_port]: Doing nothing" } } when HTTP_CLASS_SELECTED { If the request is being redirected, disable ASM if {$redirect}{ Enable ASM by default PLUGIN::disable ASM } else { Enable ASM by default PLUGIN::enable ASM } }
Aaron - Don_22992
Nimbostratus
Aaron,
The above rule did not work. I receive the following TCL error stating that the "redirect" variable does not exist.
Apr 9 14:28:25 tmm tmm[1640]: 01220001:3: TCL error: stg-errors - can't read "redirect": no such variable
while executing "if {$redirect}{
log local0. "[IP::client_addr] disabling ASM"
PLUGIN::disable ASM
} else { l
log local0. "[IP::client_addr] enabling ..."
:|
DJ
Recent Discussions
Related Content
DevCentral Quicklinks
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com
Discover DevCentral Connects
