qqdixf5_74186
Dec 17, 2007Nimbostratus
http::retry question
I am having some problems with a rule which uses http::retry command. What I am trying to do here is authentiting the request against an external service. When a request comes in, an auth request is sent to the auth service and based on the response, the original request is either rejected or sent to the backend. I have the iRule partially working, which means, it works for some requests, but not all. By adding extra logging and tcpdump at the LTM, I see some requests failed with "Bad Request(Invalid Hostname)" error.
When I first wrote the iRule, I was following an example here and using a simple flag to indicate if the request need authentication. I thought after the authentication passed the request would be sent to the selected pool directly. But somehow, it turned out that the rule was applied to the request again(Is this the way how BigIP handle this?). So I had to add a custom header in the request to avoid getting into an infinite authenticating loop. That's the only change I made to the request. I am not sure why some requests are failing. Hoping I can get some help here. Thank you!
Here is the rule:
when CLIENT_ACCEPTED {
set the flag to control lookup
set lookup 0
}
when HTTP_REQUEST {
set the lookup flag. Value 0 means the request needs to be
looked up
set lookup 0
if ([HTTP::header exists "Authenticated"]) {
set lookup [HTTP::header "Authenticated"]
}
if {$lookup == 0} {
save original request
set original_request [HTTP::request]
get the content length and replace the request payload with empty string
set payload_size [HTTP::payload length]
set original_payload [HTTP::payload]
HTTP::payload replace 0 $payload_size " "
inject lookup URI
HTTP::uri "/AuthService/ValidateToken.jsp?token=sometokenidfromtheoriginalrequest"
remove extra headers from the auth request.
HTTP::header sanitize "Host"
send the auth request to auth service pool
pool AUTH_SERVICE
} else {
pool SERVICE_POOLA
}
}
when HTTP_RESPONSE {
if {$lookup == 0 } {
collect first response (from lookup server) only
HTTP::collect 1
}
}
when HTTP_RESPONSE_DATA {
Reads the auth response and look for "Accepted"
if {$lookup == 0} {
check if the payload contains "Accepted".
If so, replay the original request.
if {$payload contains "Accepted"} {
log local0. "Request authenticated"
use pool SERVICE_POOLA
insert a custom http header to the original request and send it
set new_request [string map {"Host" "Authenticated: 1 Host"} $original_request]
HTTP::retry $new_request
} else {
reject the request
reject
}
}
}