Forum Discussion

Joern_Oltmann's avatar
Joern_Oltmann
Icon for Nimbostratus rankNimbostratus
Jan 28, 2013

Set cookie in http request AND response

Hi all,

 

 

this is my first Topic, so sorry if somthing wrong ;-)

 

I would like to set a cookie (if not set) in the http request. So the application see if the user are new.

 

 

The same cookie I would like to set in the http response (if not set). Erveryone an idea?

 

My first iRule, but not finished yet shows:

 

Rename a cookie by inserting a new cookie name with the same value as the original. Then remove the old cookie.

 

when HTTP_REQUEST {

 

Check if old cookie exists in request

 

if { [HTTP::cookie exists "_global"] } {

 

everything ok, cookie exists

 

} else {

 

TODO: create unique session

 

set new_session = [UnixTimeWithNanoSeconds]

 

Flag the request / session as new (for other systems)

 

HTTP::header insert "X-Global-Session" "New"

 

Insert new global cookie with session value

 

HTTP::cookie insert name "_global" value $new_session

 

}

 

}

 

 

Set cookie if a new Cookie was generated

 

when HTTP_RESPONSE {

 

TODO: check if new session

 

if { $new_session > 0 } {

 

insert new global cookie and transport it to the client

 

HTTP::cookie insert name "_global" value $new_session

 

 

reset state

 

set new_session = 0

 

}

 

}

 

Thanks for help

 

Joern

 

8 Replies

  • Hi Joern,

     

    What is the ultimate goal of the iRule if you don't mind me asking? Is the application trying the track HTTP_Header for a new client? Are you trying to establish persistence?

     

     

    =Bhattman=

     

  • … the whole irule tries to solve 2 things:

     

    1) generate a global tracking session which is already created within the first request. it will never be used for authentication

     

    2) provide a HTTP header for any system behind the f5 to mark the global tracking session as new

     

  • http://devcentral.f5.com/Community/GroupDetails/tabid/1082223/aff/5/afv/topic/aft/2163201/afc/2263687/Default.aspx

     

     

    Here are two options. The rand option should be more efficient but not cryptographically secure. You can compare the CPU usage using the timing command.

     

     

    Use rand() to generate a psuedo-random 8 digit number (not cryptographically secure)

     

    format %010s [expr { int(100000000 * rand()) }]

     

     

    Use AES::key to generate a cryptographically secure unique ID

     

    set uid [string range [AES::key 256] 8 end]

     

     

    Use timing to do a performance comparison:

     

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

     

     

    Aaron
  • Expanding on Aaron's recommendation, I typically use the concatenation of two AES functions to return a unique ID:

    Ex.

    set session_key "[string range [AES::key 128] 15 end][string range [AES::key 128] 15 end]"

    And here's something that might work for you:

    
    when HTTP_REQUEST {
    if { not ( [HTTP::cookie exists _global] ) } {
    set session_key "[string range [AES::key 128] 15 end][string range [AES::key 128] 15 end]"
    HTTP::header insert "X-GLOBAL-Session" "New"
    HTTP::cookie insert name "_global" value $session_key
    }
    }
    when HTTP_RESPONSE {
    if { [info exists session_key] and $session_key ne "" } {
    HTTP::cookie insert name "_global" value $session_key
    unset session_key
    }
    }
    

  • its just the possibility for any other system (including i.e. monitoring like munin) to gain the information about new created global sessions somewhere in the request

     

  • Thanks all for help,

    Someone suggestions for improvement, now I will use this iRule.

    
    when RULE_INIT {
      log local0. "Running RULE_INIT of iRule 'global_tracking_cookie'"
       Global Session Name
      set static::globalSessionName "_global"
       Session (Idle) timeout in seconds (10 year = 31536000 seconds)
      set static::globalSessionTimeout 31536000
       Header for New Global Session
      set static::globalSessionHeader "X-Global-Session"
      set static::globalSessionHeaderValueNew "new"
      log local0. "iRule 'global_tracking_cookie' initialized: sessionName($static::globalSessionName), sessionTimeout($static::sessionTimeout)"
    }
    
    when HTTP_REQUEST {
      if { not [HTTP::cookie exists $static::globalSessionName] } {
         INFO: generate global tracking session
         main_domain like "wlw.de"
        set main_domain_pos 2
        if { [string tolower [HTTP::host]] ends_with ".co.uk" } {
           main_domain is "wlw.co.uk"
          incr main_domain_pos 1
        }
        if { [string tolower [HTTP::host]] contains "onlinetest" } {
           main_domain is "onlinetest.wlw.(de|co.uk)"
          incr main_domain_pos 1
        } elseif { [string tolower [HTTP::host]] contains ".webdev." } {
           main_domain is "preview.webdev.wlw.(de|co.uk)"
          incr main_domain_pos 2
        }
        set main_domain [domain [HTTP::host] $main_domain_pos]
        set new_session_value "[string range [AES::key 128] 15 end][string range [AES::key 128] 15 end]"
         set http header and cookie
        HTTP::header insert $static::globalSessionHeader $static::globalSessionHeaderValueNew
        HTTP::cookie insert name $static::globalSessionName value $new_session_value
         cleanup
        unset main_domain_pos
      }
    }
    
    when HTTP_RESPONSE {
      if { [info exists new_session_value] } {
         INFO: transport the new global tracking cookie to the client
        HTTP::cookie insert name $static::globalSessionName value $new_session_value domain $main_domain
        HTTP::cookie expires $static::globalSessionName $static::globalSessionTimeout
         cleanup
        unset main_domain new_session_value
      }
    }