Forum Discussion

Nicolas_Bellen1's avatar
Nicolas_Bellen1
Icon for Nimbostratus rankNimbostratus
Jun 03, 2011

REGEX Alternatives

I've been trying to figure out how i'd structure a particular portion of my iRule to look for values contained in a string, instead of a regular expression but i'm having some difficulty:

 

 

The first conditional is straightforward and has a static value. However the second conditional would be DRC followed by 5 numbers. Is there any way to structure this so it uses a more efficient method? Here's what i have:

 

 

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

 

([HTTP::uri] matches_regex {DRC(\d)+})}

 

 

The other issue i'm running into is how i would replace the host portion of the redirect location, yet leave the URI intact. I tried the following, but couldn't quite figure out how to structure the first parameter of the string map to match on the host portion without using a regular expression. I borrowed this portion (from http://devcentral.f5.com/wiki/default.aspx/iRules/RewriteHTTPRedirectHostname.html), but couldn't quite piece it together.

 

 

if { [HTTP::is_redirect] } {

 

HTTP::header replace Location [string map -nocase {"abc.example.com" "def.example.com"} [HTTP::header value Location]]}

 

 

Any help would be appreciated!

 

 

Nick

 

  • Hi Nick,

     

     

    You can use string match to do the first part:

     

     

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

     

     

    You could make the mastermenu and DRC checks more specific by using either HTTP::path or HTTP::query instead of HTTP::uri.

     

     

    I tried the following, but couldn't quite figure out how to structure the first parameter of the string map to match on the host portion without using a regular expression.

     

     

    Can you clarify this? Do you have multiple hosts that you're trying to rewrite in the redirect? Or do you want to rewrite all hosts to "def.example.com"? You can parse the host from the redirect location using URI::host:

     

     

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

     

     

    Aaron
  • Aaron,

     

     

    I tried using URI::host but it didn't give me the expected results. Here's what i have:

     

     

    if { [HTTP::is_redirect] } {

     

    set url [HTTP::header value Location]

     

    set host [URI::host $url]

     

    log local0. "Original Location: [HTTP::header value Location]"

     

    HTTP::header replace Location [string map -nocase {$host "def.example.com"} [HTTP::header value Location]]

     

    log local0. "Updated Location: [HTTP::header value Location]"

     

    }

     

     

    In the logs i am seeing no change. To answer your previous question, i'd like to match the host portion of anything in the header upon a redirect and swap it out with "def.example.com"

     

     

    Nick

     

  • The values for most HTTP:: commands are cached within the same event and priority. If you don't specify an event priority a default of 500 is used. You can use a later priority event (like 501) to view the change from the iRule. Also, the curly braces in string map will prevent command and variable substitution. You can use double quotes instead:

    ...
       if { [HTTP::is_redirect] } {
          log local0. "Original Location: [HTTP::header value Location]"
          HTTP::header replace Location [string map -nocase "[URI::host [HTTP::header value Location]] def.example.com" [HTTP::header value Location]]
       }
    }
    when HTTP_RESPONSE priority 501 {
       log local0. "Updated Location: [HTTP::header value Location]"
    }
    

    Aaron
  • Aaron,

     

     

    That worked beautifully! I have one more question regarding REGEX alternatives as it relates to the iRule i'm working on.

     

     

    Is there a more efficient method to do the following, versus the REGEX i'm currently using?

     

     

    when HTTP_RESPONSE_DATA {

     

     

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

     

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

     

     

    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 "example.com" path "/"

     

     

    Replace embedded URL to Oasis Host with URL to VIP of abc.example.com

     

    STREAM::expression {@GMVM(\d)+\.oasis\.local@abc.example.com@}

     

    STREAM::enable

     

    }

     

    }

     

     

    I'm having a bit of difficulty wrapping my head around when i can use regular expression rules to match on items using strings instead.

     

     

    Nick

     

  • Hi Nick,

     

     

    The only option I can think of is if there are a static number of digits after the GMVM string. If so, you could potentially use string match to check for a match and then parse the hostname. However, I'm not sure that's going to be very elegant compared with the regexp command.

     

     

    Once you get that version of the iRule working, you could consider testing a version which uses regsub from HTTP_RESPONSE_DATA to replace the internal hostname with the external one. It might be simpler than using a payload collect and a stream expression.

     

     

    Aaron