Forum Discussion

Branden_35485's avatar
Branden_35485
Icon for Nimbostratus rankNimbostratus
Jun 14, 2012

LTM v11 iRule Migration

I am trying to upgrade a customer to a new LTM box running v11. There current box is running v10.1.2.

 

 

The iRule that they use is not working correctly on v11 or v10.2.3. What happens is when a user clicks on a web page for the first time the iRule runs correctly and the user is presented with the correct webpage in a new window, which is correct. Now if they leave the previous window open and try a different link the iRule runs correctly again.

 

 

 

However, if they close the first window and try a different link the iRule does not run. If you wait approx 60secs and try it again the iRule runs correctly again.

 

 

 

The iRule that they are using I did not create. I know that there are differences for some iRules between versions. I tried looking on F5 knowledge base for the differences and I was unable to locate a difference in the iRule.

 

 

 

So I am just wondering if anyone has run into this issue before? I also am not sure if the iRule is even the problem. So any feed back is appreciate the iRule is posted below.

 

 

 

 

 

 

This iRule parses incoming requests for a particular value in the URI. If present it

 

will replace the HTTP header and destination IP address with a value retrieved from a

 

predefined HTTP cookie. It also takes HTTP responses and parses the payload for a

 

particular string. If present, it will store this value in an HTTP cookie and replace

 

it with a predefined value.

 

 

DevCentral Wiki on HTTP cookie encoding details:

 

http://devcentral.f5.com/wiki/default.aspx/iRules/HTTP__cookie.html

 

DevCentral for matching on HTTP payload

 

http://devcentral-llix.f5.com/Community/GroupDetails/tabid/1082223/asg/50/aft/1397/showtab/groupforums/Default.aspx

 

DevCentral for selecting pool members based on URL Query

 

http://devcentral.f5.com/wiki/default.aspx/iRules/Select_pool_member_based_on_HTTP_query_string_parameter.html

 

DevCentral for using data group list

 

http://devcentral.f5.com/Community/GroupDetails/tabid/1082223/asg/50/aft/24061/showtab/groupforums/Default.aspx

 

DevCentral for using stream profiles

 

http://devcentral.f5.com/Tutorials/TechTips/tabid/63/articleType/ArticleView/articleId/101/LTM-stream-profile-Multiple-replacements-regular-expressions.aspx

 

http://devcentral.f5.com/wiki/default.aspx/iRules/stream__expression

 

 

 

when HTTP_REQUEST {

 

 

 

Log debug to /var/log/ltm? 1=yes, 0=no.

 

set debug 0

 

 

 

Disable the stream filter for all requests

 

STREAM::disable

 

 

 

Set the node and URL to the value contained in the cookie

 

if {([string tolower [HTTP::uri]] contains "mastermenu") ||

 

([string tolower [HTTP::uri]] contains "GISOasis/Login.aspx?Logout=true") ||

 

([string tolower [HTTP::uri]] contains "oasisaccounting") ||

 

([string tolower [HTTP::uri]] contains "oasisclaims") ||

 

([string match -nocase {*DRC[0-9][0-9][0-9][0-9][0-9]*} [HTTP::uri]])} {

 

 

 

Set URL original hostname of Oasis Host

 

set Cookie_URL [string tolower [HTTP::cookie "DRCShared_IP"]]

 

HTTP::header replace Host $Cookie_URL

 

 

 

Search for value in data group set list matching Oasis Host

 

set Cookie_Node [class search -value OASIS_LIST equals $Cookie_URL]

 

 

 

if {$debug != 0} {

 

log local0. "Node $Cookie_Node is being used for $Cookie_URL"

 

log local0. "[IP::client_addr]:[TCP::client_port]: Debug enabled on [HTTP::method] request for [HTTP::host][HTTP::uri]"

 

}

 

 

 

node $Cookie_Node 80

 

}

 

 

 

Prevent the server from sending a compressed response

 

remove the compression offerings from the client

 

HTTP::header remove "Accept-Encoding"

 

 

 

Don't allow data to be chunked

 

if { [HTTP::version] eq "1.1" } {

 

 

 

Force downgrade to HTTP 1.0, but still allow keep-alive connections.

 

Since 1.1 is keep-alive by default, and 1.0 isn't,

 

we need make sure the headers reflect the keep-alive status.

 

 

 

Check if this is a keep alive connection

 

if { [HTTP::header is_keepalive] } {

 

Replace the connection header value with "Keep-Alive"

 

HTTP::header replace "Connection" "Keep-Alive"

 

}

 

Set server side request version to 1.0

 

This forces the server to respond without chunking

 

HTTP::version "1.0"

 

}

 

}

 

 

 

when HTTP_RESPONSE {

 

 

 

Trigger collection for up to 1MB of data

 

Mandatory for buffering data in HTTP_RESPONSE_DATA

 

if {[HTTP::header exists "Content-Length"] && [HTTP::header "Content-Length"] <= 1048576}{

 

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

 

} else {

 

set content_length 1048576

 

}

 

Check if $content_length is not set to 0

 

if { $content_length > 0} {

 

HTTP::collect $content_length

 

}

 

 

 

Check if response is a 404 error code and redirect to gis.grinnellmutual.com if it is

 

if { [HTTP::status] == "404"} {

 

HTTP::redirect "https://gis.grinnellmutual.com"

 

}

 

 

 

Check for redirect and if location URI::host is present and rewrite to gis.grinnellmutual.com

 

if { [HTTP::is_redirect] && [string length [URI::host [HTTP::header value Location]]] } {

 

Replace embedded URL to Oasis Host with URL to VIP of gis.grinnellmutual.com

 

HTTP::header replace Location [string map -nocase "http:// https:// [URI::host [HTTP::header value Location]] gis.grinnellmutual.com" [HTTP::header value Location]]

 

}

 

 

 

}

 

 

 

when HTTP_RESPONSE_DATA {

 

 

 

Log debug to /var/log/ltm? 1=yes, 0=no.

 

set debug 0

 

set found -1

 

 

 

Check for the FQDN of domain oasis.local in the payload

 

regexp -nocase {GMVM(\d)+\.oasis\.local} [HTTP::payload] found

 

 

 

if {$debug != 0} {

 

log local0. "[HTTP::payload]"

 

log local0. "$found is being replaced by gis.grinnellmutual.com"

 

log local0. "[IP::client_addr]:[TCP::client_port]: Debug enabled" }

 

 

 

if {$found != -1} {

 

Insert a new cookie with the old host IP name and old cookie's value

 

HTTP::cookie insert name "DRCShared_IP" value $found domain "grinnellmutual.com" path "/"

 

 

 

Replace embedded URL to Oasis Host with URL to VIP of gis.grinnellmutual.com

 

STREAM::expression {@http://GMVM(\d)+\.oasis\.local@https://gis.grinnellmutual.com@ @http://gmvm(\d)+\.oasis\.local@https://gis.grinnellmutual.com@}

 

STREAM::enable

 

}

 

}

 

2 Replies

  • Hi Branden,

     

     

    There's a lot going on with that iRule. I'd start by making sure you have a OneConnect profile enabled on the virtual server. If you have SNAT enabled on the virtual server, you can use the default OneConnect profile with a /0 source mask. Else, create a custom OneConnect profile with a /32 source mask. If you still see issues with the iRule, try enabling debug and check the output in /var/log/ltm when a failure occurs.

     

     

    That said, there are a few issues/oddities with the iRule:

     

     

    1. This condition will never be true as you're setting the URI to lowercase and then checking for a mixed case string:

     

    ([string tolower [HTTP::uri]] contains "GISOasis/Login.aspx?Logout=true")

     

     

    You can replace that whole section with a switch statement to avoid repeating the same [string tolower...] operation on the URI:

     

     

    
     Set the node and URL to the value contained in the cookie
    switch -glob [string tolower [HTTP::uri]] {
    "*mastermenu*" -
    "*gisoasis/login.aspx?logout=true*" -
    "*oasisaccounting*" -
    "*oasisclaims*" -
    "*drc[0-9][0-9][0-9][0-9][0-9]* {
    

     

     

    2. The iRule combines HTTP payload collection with a stream profile. You should either do one or the other but not both. For payload rewriting only, it's more efficient to just use a stream profile. If you need to insert a cookie based on the payload content, I think you'll need to collect the payload.

     

     

    3. If the response is a 404, you can just redirect the request and skip the rest of the response logic. So you could move this section to the top of HTTP_RESPONSE and add a return statement to avoid the rest of the code:

     

     

    when HTTP_RESPONSE {

     

    Check if response is a 404 error code and redirect to gis.grinnellmutual.com if it is

     

    if { [HTTP::status] == 404} {

     

    HTTP::redirect "https://gis.grinnellmutual.com"

     

    return

     

    }

     

     

    Aaron
  • Hi hoolio,

     

     

    Thanks for the response. Yes I know there is a lot going on with that iRule.

     

     

     

    I thought I had the default OneConnect Profile enabled however I did not. SNAT is enabled on the virtual server default AutoMap.

     

     

     

    1. This would explain why the Logout button does not work.

     

     

     

    2. I am unfamiliar with stream profiles. Like I said before I did not create this iRule and I am not 100% sure on what is needed. However, I am pretty sure I need to insert a cookie based on payload content. If you could point me in the direction for information or if you could help me out I would greatly appreciate it.

     

     

     

    3. Will move that

     

     

     

    Thanks again.