Case Insensitive Comparisons

Much of the power of a scripting language is in the ability to use the logical operations contained within it to make comparisons of pieces of data. These comparisons come in many forms, but one of the most common is a string comparison. This means basically that you're looking at two free-form pieces of data in an alphanumeric format and making some sort of comparison. Whether you're looking for equality or certain differences depends on what you're trying to accomplish and the data you started with. This is one of the most rudimentary and core abilities of scripting in general, and is definitely highly leveraged in iRules.

When trying to make a comparison there are many things to keep in mind. Data types, the desired outcome, operator functions and flags, and, in the case of a string comparison, case sensitivity. The idea of case sensitivity is an easy one. In its most basic form "Sensitive" does not equal "sEnSiTiVe". They are not alike, due to the differences in case. This notion of case effecting equality in string comparisons becomes especially important in languages such as TCL, which iRules is based on, wherein all data can be represented in string format. In such cases it becomes exceedingly important to ensure that you're dealing with the proper string case when performing comparisons as to not end up with the incorrect result.

The issue of case sensitivity is compounded by the fact that many of the most used operators in iRules (and TCL) don't have a built in function for dealing with case sensitivity - eq, ==, ne, !=, contains, starts_with, ends_with, findstr, getfield - none have built in case insensitivity, which means you'll have to take matters into your own hands. Thankfully there are many different mechanisms for dealing with this manually in an iRule. There are really two different options when dealing with case sensitivity. First is to make use of one of the several commands that has the ability to make case insensitive comparisons by default. I won't go into all of them here, but a couple such commands are:

lsearch - nocase:

lsearch -all {a b c a b c} C

Returns nothing

lsearch -all -nocase {a b c a b c} C

Returns: 2 5

The other option is to change the value that you're going to be making the comparison against to a single case prior to passing it through the comparison operation in question. In this way, we can assume that the string is going to be all uppercase or all lowercase, and code accordingly. To perform such a change you'll likely be making use of the string command and either the tolower or toupper sub-commands. These commands take the given string argument and create a copy of it in memory with a single case. This copy is then used for comparison instead of the original string. In this way you can have a completely case insensitive match without modifying the value of the string you're comparing. For instance the two below examples show first the case sensitive version of a simple iRule, followed by the version made case insensitive via the string tolower command.

Case Sensitive:

when HTTP_REQUEST {
  if { [HTTP::uri] contains "MySite" } {
    HTTP::redirect http://www.domain.com[HTTP::uri]
  }
}

Case In-sensitive

when HTTP_REQUEST {
  if { [string tolower [HTTP::uri]] contains "mysite" } { 
    HTTP::redirect http://www.domain.com[HTTP::uri]
  }
}

Notice that the first comparison would match a very specific case. This means that if a user mis-typed the URI as mysite, MYSite, mySite, or any other permutation, the comparison would not return positively, and the redirection wouldn't occur. The second example, however, is completely tolerant of any case combination the user might enter, thanks to the string tolower command. Keep in mind that no data was actually changed by this operation, so it is completely transparent.

This simple practice is something that's important to keep in mind when building any code, especially your iRules, as there are many times you'll be looking to key off of user data that can take many formats you might not expect. For further research on which commands have built in options for case insensitivity I'd recommend taking a look through the general TCL documentation up on SourceForge. If you're looking to learn more specifically about how to make use of the string tolower/toupper commands I'd take a peak on DevCentral as there are many, many examples of this in the forums, the CodeShare and blogs. You'll probably also want to peruse the doc page for the string command for a peek at the official word on the subject.

Published May 28, 2008
Version 1.0
  • lsearch only gets the -nocase flag in 8.5 (not in 8.4 which is what iRules are based on).

     

     

    Aaron