Forum Discussion

colincashin_171's avatar
colincashin_171
Icon for Nimbostratus rankNimbostratus
Oct 25, 2012

iRule to persist based on phpsessid

Hi

 

I am looking for guidance on setting up persistence based on phpsessid. We are load balancing across 2 Apache web servers and are using phpsessid for persistence between the servers. I would like to setup an iRule to track the phpsessid in HTTP request/responses and persist to the correct server.

 

I have used the wiki @ https://devcentral.f5.com/wiki/iRul...sistence.ashx to try and achieve this with the following iRule code:

 

 

when RULE_INIT {

 

set ::debug 0

 

}

 

when HTTP_REQUEST {

 

set sessionID ""

 

set sessionID [findstr [HTTP::path] "PHPSESSID=" 10 26]

 

set persistTo [session lookup uie $sessionID]

 

if { $persistTo equals "" } {

 

pool [LB::server pool]

 

if {$::debug}{log local0. "No phpsession ID, load balancing the connection."}

 

} else {

 

pool [LB::server pool] member $persistTo

 

if {$::debug}{log local0. "PHPSESSID $sessionID sent to $persistTo"}

 

}

 

}

 

when HTTP_RESPONSE {

 

set sessionID ""

 

set sessionID [findstr [HTTP::path] "PHPSESSID=" 10 26]

 

set persistTo [session lookup uie $sessionID]

 

if { $persistTo equals "" } {

 

session add uie $sessionID [IP::server_addr] 1800

 

if {$::debug}{log local0. "added server entry $persistTo for PHPSESSID $sessionID"}

 

} else {

 

if {$::debug}{log local0. "existing server entry $persistTo for PHPSESSID $sessionID"}

 

}

 

}

 

when LB_FAILED {

 

If no servers are active, redirect to sorry page elsewhere

 

if {[active_members [LB::server pool]] == 0}{

 

HTTP::redirect http:://sorry.domain.com/NoServersAvail.html

 

if {$::debug}{log local0. "No servers available. Redirecting to sorry server."}

 

} else {

 

LB::detach

 

LB::reselect [LB::server pool]

 

if {$::debug}{log local0. "LB failed, re-load balancing to pool."}

 

}

 

}

 

 

The PHPSESSID is 26 characters long.

 

I have assciated this iRule with a Universal persistence profile and applied to Virtual Server. However when testing I receive the following error:

 

 

TCL error: irule-phpsessid - wrong args: should be "session lookup uie " while executing "session lookup uie $sessionID"

 

 

Whats confusing me is how to check the server response using HTTP:: ?

 

This topic was been touched on before:

 

https://devcentral.f5.com/Community...fault.aspx

 

 

Any guidance here greatly appreciated. I'm consuming a *lot* of iRule doco in the process of getting this working. Way cool stuff

 

3 Replies

  • I would like to setup an iRule to track the phpsessid in HTTP request/responses and persist to the correct server.where is phpsessid in http response? is it in cookie or custom http header?

     

     

    set sessionID [findstr [HTTP::path] "PHPSESSID=" 10 26]is PHPSESSID in http path (not query)?

     

     

    HTTP::path

     

    https://devcentral.f5.com/wiki/iRules.http__path.ashx

     

     

    TCL error: irule-phpsessid - wrong args: should be "session lookup uie " while executing "session lookup uie $sessionID"i think it is error because $sessionID is null.

     

     

    anyway, is the irule in Configuring a universal persistence profile section not usable?

     

     

    sol7392: Overview of universal persistence

     

    http://support.f5.com/kb/en-us/solutions/public/7000/300/sol7392.html
  • Hi Colin,

     

     

    Welcome to DC!

     

     

    You can check to see if $sessionID ne "" before using it in the session commands to avoid this runtime error.

     

     

    Aaron
  • Thanks nitass@ and hoolio@

     

     

    The code snippet I included is indeed incorrect - the phpsessid is set in the set-cookie response from the server and not HTTP::path. I had a look at the Universal Profile section (http://support.f5.com/kb/en-us/solutions/public/7000/300/sol7392.html) and read through all options around HTTP::cookie and found that this greatly simplified approach works perfectly! I had completely over-engineered the solution for what I was trying to achieve.

     

     

    What I now have in place (and works perfectly) is:

     

     

     when HTTP_RESPONSE {
      if { [HTTP::cookie exists "PHPSESSID"] } {
        persist add uie [HTTP::cookie "PHPSESSID"]
      } 
    } 
    when HTTP_REQUEST {
      if { [HTTP::cookie exists "PHPSESSID"] } {
       persist uie [HTTP::cookie "PHPSESSID"] 
     }
    } 

     

     

    Whats key is that in

     

     

     persist add uie [HTTP::cookie "PHPSESSID"] 

    the HTTP::cookie name snippet: this gets the value of an existing cookie with the given name so it extracts the 26 character phpsessid from the set-cookie headers. Nice! Then we just persist based on this. Thanks for the assistance folks. I'm looking forward to making positive contributions to the community as I learn more about the platform 🙂