Forum Discussion

Conor_Cunningha's avatar
Conor_Cunningha
Icon for Nimbostratus rankNimbostratus
Oct 03, 2008

Persistence and 302 Redirects

G'day,

I have a service which works as follows.

2 or more application nodes.

Users than can reside on any node, but once on a node, do not move.

On top of this I have a Big IP box load balancing between the two or more nodes.

The traffic originates from a client. The traffic is HTTP POST (no GETS are used) with XML and it works as follows.

Scenario 1.

User 1 logs into Virtual Service on the Big IP. Traffic is load balanced off to node 1 where the user 1 lives. Node 1 replies with a HTTP response containing a SessionID of 22 characters wrapped up in abcde...... The Big IP should see this, and persists all requests with that sesssionID to node 1.

Scenario 2.

User 2 logs into Virtual Services. Traffic is load balanced off to node 2 but user 2 resides on node 1. Node 2 replies with a HTTP 302 with a Location: IPADDRESS in the HTTP Header. This IP Address contains only an IP address and refers to the node where the user in question resides.

Here is where I get lost. I want the Big IP to forward the original HTTP response to the Location contained in the HTTP 302 response to the corresponding node (in this case node 1)

After which node 1 should reply with a HTTP response containing a SessionID as above in scenario 1, this SessionID should be read and stored by the Big IP, and all further sessions containing that SessionID are to be forwarded to the node in accordance with the persistence table.

At the moment if a user logs in and is directed to the correct node, things work well. However, if a user is directed to a node where he does not live I run into problems. Namely, getting a SessionID in the HTTP_Request event when the HTTP request doesn't contain one and then basically stalling.

I can't work out how to manage the redirect thing. Any advice is well and truly appreciated.

Cheers,

Conor

I have The following iRule

when RULE_INIT {

log local0.alert "Rule Init"

}

when CLIENT_ACCEPTED {

log local0.alert "From [IP::remote_addr]:[TCP::remote_port] to [IP::local_addr]:[TCP::local_port]"

set PersistTo ""

set sessid "0"

set redirLocation ""

}

when HTTP_REQUEST {

log local0.alert "HTTP method [HTTP::method] - [HTTP::host] - [HTTP::uri]"

set method [HTTP::method]

if { $method == "POST" } {

log local0.alert "Method is POST"

log local0.alert "sessid: $sessid"

Grab the request for later use if redirect

set request [HTTP::request]

}

if { $sessid != "0" } {

session add uie $sessid [LB::server addr] 30

set PersistTo [session lookup uie "$sessid"]

log local0.alert "added Persistence: $PersistTo"

}

HTTP::collect 2048

}

when HTTP_REQUEST_DATA {

set payloadrequest [HTTP::payload]

if { $payloadrequest contains "SessionID" } {

get the sessionID!

set sessid [findstr $payloadrequest SessionID 10 22]

log local0.alert "sessid in request is: $sessid"

}

}

when LB_SELECTED {

log local0.alert "Server Selected: [LB::server pool] [LB::server addr]:[LB::server port]"

if { $sessid != "0" } {

set PersistTo [session lookup uie "$sessid"]

log local0.alert "PersistTo: $PersistTo"

if {$PersistTo == ""} {

log local0.alert "None Persistense, using: [LB::server addr] Pool: [LB::server pool]"

log local0.alert "None Persistense, sessid = $sessid"

persist add uie $sessid 30

set PersistTo [session lookup uie "$sessid"]

log local0.alert "added Persistence: $PersistTo"

}

else {

log local0.alert "using Persistence: [session lookup uie "$sessid"]"

}

}

}

when SERVER_CONNECTED {

log local0.alert "Connect from IP: [IP::local_addr]:[TCP::local_port] to [IP::remote_addr]:[TCP::remote_port]"

}

when HTTP_RESPONSE {

log local0.alert "HTTP Status: [HTTP::status]"

set initclen [HTTP::header "Content-Length"]

set redirLocation [HTTP::header "Location"]

if { $initclen > 0 } {

set clen [HTTP::header "Content-Length"]

} else {

set clen 2048

}

if { $clen > 0 } {

HTTP::collect $clen

}

if { [HTTP::is_redirect] } {

set session Id to null

set sessid "0"

log local0.alert "HTTP Status: We have redirect"

log local0.alert "Redirection Location: $redirLocation"

log local0.alert "Ip of Redir is : $redirLocation"

set the cluster node in imps5-pool and resend original login request

pool test-pool member $redirLocation 8080

}

}

when HTTP_RESPONSE_DATA {

set payload [HTTP::payload]

if { $payload contains "SessionID" } {

get the sessionid!

set sessid [findstr $payload SessionID 10 22]

session add uie $sessid $redirLocation 30

persist add uie $sessid 30

HTTP::retry $request

log local0.alert "sessid in response is: $sessid"

}

}