Forum Discussion

abewu_915's avatar
abewu_915
Icon for Nimbostratus rankNimbostratus
Nov 15, 2007

iRule not working when HTTP cookie header exceeds certain length?

Hello there,

 

 

I've got a simple iRule that

 

rewrites the "Cookie Insert" cookie domains by chopping off the first

 

part before the period (so the cookie domain "www.mydomain.com" becomes

 

".mydomain.com"). We've got 10+ websites and it's working on all

 

of them except one site (just to be really original, I'll call it site "A").

 

 

Does anyone know why the F5 would behave differently depending on the

 

number of cookies set for a particular site? Perhaps the "HTTP::cookie

 

exists" command doesn't work when cookie HTTP header sent in the request

 

exceeds a certain length?

 

 

The other config settings are exactly the same (HTTP

 

virtual server, HTTPS virtual server, port 0 pool shared by both, Cookie

 

Insert as primary persistence with Source Affinity as fallback persistence,

 

Least Connections Node load balancing algorithm).

 

 

The only observable difference between the sites that are working

 

and the site that is not working is the fact that the broken site "A"

 

sets more cookies on the user's browser (10 including the F5 cookies vs

 

7 on the other sites). If I remove all my cookies and restart my browser,

 

the F5 will rewrite the cookie domain as expected.

 

 

Any info would be HUGELY appreciated.

 

 

Thanks in advance,

 

abe

 

 

 

This rule provides the following functionality:

 

 

- rewrites the domain of the given cookie to the given domain

 

 

Requirements:

 

- none.

 

 

Background:

 

 

The built-in F5 web GUI does not allow configuration of the cookie domain that the Cookie Insert persistence algorithm uses.

 

Therefore, the F5 will, by default, insert 2 different cookies for HTTP and HTTPS with different cookie domains (for example,

 

one cookie with domain=www.mydomain.com and another with domain=secure.mydomain.com).

 

 

This rule attempts to make up for that.

 

It ensures that the cookie domain is the same for both cookies, so that there is only 1 cookie (eg, domain=.mydomain.com).

 

This way, the F5 uses the same cookie to persist sessions and therefore persists across HTTP and HTTPS (directs the

 

customer to the same web server for HTTP and HTTPS requests).

 

 

The cookie name will be generated dynamically based on the server pool. The domain will be generated dynamically

 

based on the host in the URL (chops off the portion before the first dot, ie, "www.mydomain.com" becomes

 

".mydomain.com"

 

 

when LB_SELECTED {

 

Set the Cookie Name automatically based on the server pool name

 

set ::cookie_name "BIGipServer[LB::server pool]"

 

log "cookie_name $::cookie_name"

 

}

 

 

when HTTP_REQUEST {

 

Find the correct cookie domain dynamically based on the host in the URL.

 

set host [HTTP::host]

 

Use the substring from the first dot to the end of the string.

 

set ::cookie_domain [findstr $host "."]

 

Set the Cookie Domain for this site

 

log "cookie domain is $::cookie_domain"

 

}

 

 

when HTTP_RESPONSE {

 

We need to rewrite the cookies used by the application, because they have the wrong domain.

 

if {[HTTP::cookie count] > 0}{

 

if {[HTTP::cookie exists "$::cookie_name"]}{

 

set cookie_value [HTTP::cookie value "$::cookie_name"]

 

set cookie_path [HTTP::cookie path "$::cookie_name"]

 

log "$::cookie_name value $cookie_value path $cookie_path $::cookie_domain"

 

HTTP::cookie remove "$::cookie_name"

 

HTTP::cookie insert name "$::cookie_name" value "$cookie_value" path "$cookie_path" domain "$::cookie_domain"

 

}

 

}

 

}

4 Replies

  • First thing... you're using global variables (Ex: $::cookie_name) when it looks like the data is specific to the connection. Can you first try removing the :: from the variable names to use local variables (Ex: $cookie_name)?

     

     

    Also, I don't think you need to save the name and value of the cookies and then re-insert them with the updated domain. You can just set the domain using: 'HTTP::cookie domain $cookie_name $my_domain'.

     

     

    Lastly, do you have multiple pools that could be used per individual virtual server? ie, are you using another rule to select a pool? If not, you can get move the code from LB_SELECTED to HTTP_REQUEST to consolidate.

     

     

    Can you retest with local variables and see if you still encounter the failure?

     

     

    Aaron
  • FWIW, RFC 2965 outlines cookie specs, and I believe both IE and Firefox keep to the 4096 byte max for the cookie header, and 20 cookies per domain. So you should be OK with 10 cookies, but it needs to be under 4k total.

     

     

    Denny
  • Thank you for the info. I will definitely try your suggestions and post my findings.
  • The new iRule worked great! Thank you for your help! For reference, here is the new iRule:

     

     

    when HTTP_REQUEST {

     

    Set the Cookie Name automatically based on the server pool name

     

    set cookie_name "BIGipServer[LB::server pool]"

     

    log "cookie_name $cookie_name"

     

    Find the correct cookie domain dynamically based on the host in the URL.

     

    set host [HTTP::host]

     

    Use the substring from the first dot to the end of the string.

     

    set cookie_domain [findstr $host "."]

     

    Set the Cookie Domain for this site

     

    log "cookie domain is $cookie_domain"

     

    }

     

     

    when HTTP_RESPONSE {

     

    We need to rewrite the cookies used by the application, because they have the wrong domain.

     

    if {[HTTP::cookie count] > 0}{

     

    if {[HTTP::cookie exists "$cookie_name"]}{

     

    HTTP::cookie domain $cookie_name $cookie_domain

     

    log "rewriting cookie domain: cookie=$cookie_name, domain=$cookie_domain"

     

    }

     

    }

     

    }