HTTP::retry¶
Description¶
Re-sends a request to a server. Can be either the same or a different
request, to the same or a different server.
- To replay the same request, save the request to a variable in the HTTP_REQUEST event, then use it with this command.
- A different request may alternatively be specified. The request string must be well-formed and complete, including all required headers.
The request generated by this command triggers
HTTP_REQUEST and all subsequent client-side
events.
Note: If you want to retry a request with a payload, you should use
HTTP::collect to collect the payload and then
append the payload to the request headers retrieved using
HTTP::request in
HTTP_REQUEST_DATA.
Syntax¶
HTTP::retry <request>
v11.5+
HTTP::retry [-reset] <request>
HTTP::retry <request>¶
- Resends a request to a server. The request header must be well-formed and complete.
HTTP::retry [-reset]¶
- Resends a request to a server and resets serverside connection instead of sinking the data.
Examples¶
# Retry requests to the virtual server's default pool if the server responds with an error code (5xx status)
when CLIENT_ACCEPTED {
# On each new TCP connection track that we have not retried a request yet
set retries 0
# Save the name of the virtual server default pool
set default_pool [LB::server pool]
}
when HTTP_REQUEST {
# We only want to retry GET requests to avoid having to collect POST payloads
# Only save the request headers if this is not a retried request
if { [HTTP::method] eq "GET" && $retries == 0 }{
set request_headers [HTTP::request]
log local0. "Saving HTTP request headers: $request_headers"
}
}
when LB_SELECTED {
# Select a new pool member from the VS default pool if we are retrying this request
if { $retries > 0 } {
LB::reselect pool $default_pool
}
}
when HTTP_RESPONSE {
# Check for server errors
if { [HTTP::status] starts_with "5" } {
# Server error, retry the request if we have not already retried more times than there are pool members
incr retries
log local0. "5xx error caught: retry $retries out of [active_members $default_pool]"
if { $retries < [active_members $default_pool] } {
# Retry this request
HTTP::retry $request_headers
# Exit this event from this iRule so we do not reset retries to 0
return
}
}
# If we are still in the rule we are not retrying this request
set retries 0
}
# Retry 404 responses once to a second pool
when CLIENT_ACCEPTED {
# Track whether this is a retried request
set retried 0
# Save the name of the VS default pool
set default_pool [LB::server pool]
# Track whether we have the headers for this request
set request_headers ""
}
when HTTP_REQUEST {
# Select the VS default pool by default
pool $default_pool
# Check if this is a retried request
if {$retried == 0}{
# Only save request headers if it is a GET request
# We do not want to retry requests with payloads
if {[HTTP::method] eq "GET"}{
# Save the HTTP request headers
set request_headers [HTTP::request]
log local0. "HTTP request: $request_headers"
} else {
# Null the headers to make sure we only retry GETs
set request_headers ""
}
} else {
# Select the other pool for the retry
pool other_pool
}
}
when HTTP_RESPONSE {
# Check if we got a 404 from the default pool
if { [HTTP::status] == 404 && $request_headers ne "" && [LB::server pool] eq $default_pool } {
# Track that we are retrying this request
set retried 1
log local0. "404 error caught from default pool. Retrying."
HTTP::retry $request_headers
} else {
# Track that we are retrying this request
set retried 0
}
}
# One can save a WAN round trip by following a redirect at the LTM and responding to the
# original client request with the result of the redirect
when HTTP_REQUEST {
# Save the host header value
set host [HTTP::host]
}
when HTTP_RESPONSE {
# Check if response is a redirect based on the status code
if { [HTTP::is_redirect] } {
# Now generate a GET request to the new location
HTTP::retry "GET [HTTP::header location] HTTP/1.1\r\nHost: $host\r\n\r\n"
}
}