# Source : https://devcentral.f5.com/community/group/aft/1174729/asg/50 # Thanks to Forum User 'MaHHF5' when CLIENT_ACCEPTED { log local0. "ACC - got new connect" set retries 0 set server_needed 0 set server_selected "none" } when HTTP_REQUEST { # when opening Notes database, set server_needed 1 if {([HTTP::uri] ends_with ".nsf?OpenDatabase") and not ([HTTP::uri] contains "names.nsf") and not ([HTTP::uri] contains "iwaredir.nsf") and not ($server_selected == "new") and not ($server_selected == "orig") }{ set original_request [HTTP::request] set server_needed 1 set nsf "[substr [HTTP::uri] 1 ".nsf"].nsf" log local0. "REQ - Server needed: $server_needed" log local0. "REQ - NSF: $nsf" HTTP::uri /iwaredir.nsf/ServersLookup?OpenForm&nsfpath=$nsf log local0. "REQ - uri: /iwaredir.nsf/ServersLookup?OpenForm&nsfpath=$nsf" } else { set server_needed 0 set original_request [HTTP::request] } # when HTTP::retry with new server from X-header, select it from pool if { $server_selected == "new" } { pool [LB::server pool] member $dest log local0. "REQ - Using selected new server [LB::server addr] of pool: [LB::server pool] (Destination: $dest)" } } when LB_SELECTED { # when HTTP::retry because of 404-Code, reselect member # F5 unit sends a new session cookie if { ($retries > 0) and ($retries < 9) } { LB::reselect pool [LB::server pool] log local0. "SELE - Reselection No. $retries" } } when HTTP_RESPONSE { log local0. "RESP - Used server [LB::server addr] of pool: [LB::server pool]" # when 404-Code after automatic reselection of F5 unit to wrong server occurs, do another try if { ([HTTP::status] == 404) and ($retries < 8) } { log local0. "ALERT: 404" incr retries log local0. "RESP - Retrying original request with reselection No. $retries" HTTP::retry $original_request } # generate new session cookie (code from DevCentral) after member selection based on X-Headers because the F5 unit does not send one if { $server_selected == "new" } { set member "[LB::server addr]" scan $member "%u.%u.%u.%u" a b c d set pcookie "[scan [expr ($d<<24)|($c<<16)|($b<<8)|$a] %u].[expr 256*80].0000" HTTP::cookie insert name BIGipServer[LB::server pool] value $pcookie path "/" log local0. "RESP - New persistence cookie sent for $dest" set server_selected "none" } # build list of iNotes-Server from X-Domino Header if { $server_needed == 1} { set server_list [split [HTTP::header X-Domino-ClusterServers], ,] # set server_list2 [split [HTTP::header X-Domino-ReplicaServers], ,] # set server_list "${server_list1} ${server_list2}" # log local0. "RESP - Server_list_Cluster: $server_list1" # log local0. "RESP - Server_list_Replica: $server_list2" log local0. "RESP - Server_list: $server_list" HTTP::collect [HTTP::header Content-Length] # check if we are already on right server and then set server_selected "orig" foreach {svr} $server_list { if { "" ne $svr }{ set dest [class search -value NSLOOKUPSERVER equals "[string trim $svr]"] if {[LB::server addr] == $dest } { log local0. "RESP - Already on right server: $dest" set server_selected "orig" } } } foreach {svr} $server_list { if { "" ne $svr }{ # set dest [class search -value NSLOOKUPSERVER equals "[string trim $svr]"] # when on right server, do HTTP::retry if { $server_selected == "orig" } { log local0. "RESP - Retrying original request for original server" HTTP::retry $original_request break } # when server in list is up, do HTTP::retry if { [LB::status pool [LB::server pool] member $dest 80] eq "up" } { log local0. "RESP - Status of selected server $dest, pool [LB::server pool]: [LB::status pool [LB::server pool] member $dest 80]" set server_selected "new" log local0. "RESP - Retrying original request for new server" HTTP::retry $original_request break } } } } }