Forum Discussion
iRule pointing traffic from one pool member to another with HTTP::retry
Hi, I have the following traffic path: Client request -> External VIP ->pool with member with IP:port of internal VIP -> Internal VIP -> Pool with one member, which respond always with 307 redirect to an application server.
The idea is to break the 307 response on the LB Internal VIP and make HTTP::retry with the original request to the redirected Location.I was able to accomplish this by the iRule below.The customer responds that the iRule is working fine when a browser is used. With this type of connections, I am using cookies.When they use application for the requests (which are only POST requests), they see only a half of them on the backend server. The request-app don't support cookies, so I made X-Forwarded-For persistence, and I see the records in the persistence table for the right source IPs.All profiles are a default. Only X-Forwarded-For insertion on the external VIP.
Error on the backend server:iRule to follow...
- Kaloyan
Cirrus
Here is the iRule: when CLIENT_ACCEPTED { set server 0 set retried 0 set default_pool [LB::server pool] } when HTTP_REQUEST { set clientip "" if { [HTTP::header exists "X-Forwarded-For"] } { set clientip [lindex [ split [lindex [HTTP::header values X-Forwarded-For] 0] "," ] 0] } else { set clientip [IP::client_addr] } log local0. "persist lookup on REQUEST: $clientip" if { [HTTP::cookie exists test1] } { pool test_1 persist cookie insert test1 0 log local0. "FROM_ifcheck_cookie_exist_HDLtest1 HTTP request: [HTTP::request]" } elseif { [HTTP::cookie exists test2] } { pool test_2 persist cookie insert test2 0 log local0. "FROM_ifcheck_cookie_exist_HDLtest2 HTTP request: [HTTP::request]" } elseif { ($retried == 0) } { set request_headers [HTTP::request] Set payload content legth to capture. if {[HTTP::header exists "Content-Length"] && [HTTP::header "Content-Length"] <= 4000000}{ set content_length [HTTP::header "Content-Length"] } else { set content_length 4000000 } Capture HTTP payload from request, HTTP::collect triggers event HTTP_REQUEST_DATA if { [info exists content_length] && $content_length > 0} { HTTP::collect $content_length } pool $default_pool persist none } elseif { ($retried == 1) } { Check DGL external-ip-check for IP/X-Forwarded-For match and assign uie persistence if {[class match $clientip equals "external-ip-check"]} { switch -glob $server { "1" { pool test_1 persist uie $clientip 1800 log local0. "FROM_retried_check_SP_test1 HTTP request: [HTTP::request]" } "2" { pool test_2 persist uie $clientip 1800 log local0. "FROM_retried_check_SP_test2 HTTP request: [HTTP::request]" } default { log local0. "Configuration needed for HTTP_REQUEST. HTTP request: [HTTP::request]" } } } else { switch -glob $server { "1" { pool test_1 persist cookie insert test1 0 log local0. "FROM_retried_check_with_cookie_test1 HTTP request: [HTTP::request]" } "2" { pool test_2 persist cookie insert test2 0 log local0. "FROM_retried_check_with_cookie_test2 HTTP request: [HTTP::request]" } default { log local0. "Configuration needed for HTTP_REQUEST. HTTP request: [HTTP::request]" } } } } } when HTTP_REQUEST_DATA { Set payload, depends on HTTP::collect done in HTTP_REQUEST event. set payload [HTTP::payload] Append HTTP payload to HTTP request header to form a complete HTTP post request (request + payload) append request_headers [HTTP::payload [HTTP::payload length]] } when HTTP_RESPONSE { if { ([HTTP::status] == 307) } { log local0. "HTTP_RESPONSE from Dispatcher: [HTTP::header Location] for HTTP request: $request_headers" set retried 1 switch -glob [string tolower [HTTP::header Location]] { "*:first/*" { set server 1 HTTP::retry "$request_headers" } "*:second/*" { set server 2 HTTP::retry "$request_headers" } default { set server 0 log local0. "Configuration needed for HTTP_RESPONSE. New location from Dispatcher: [HTTP::header Location] for HTTP request: $request_headers" } } } else { log local0. "HTTP_RESPONSE from APP-server: [HTTP::response]" } }
- jurgenvdmark_14
Nimbostratus
In general I think you should add a persistency record in the HTTP_RESPONSE event via the:
commandpersist add uie
In the HTTP_REQUEST you can persist to the server by using the:
commandpersist uie
- Kaloyan
Cirrus
Thanks, jurgenvdmark. I was aware of this possibility for "persist add uie" in the HTTP_RESPONSE. Will add it as well... Right now, I am trying to completely modify the iRule, using sideband collection options, as HTTP::retry seems to have problems with these POST requests...
Recent Discussions
Related Content
* 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