Forum Discussion

Nicholas_Zurfl1's avatar
Nicholas_Zurfl1
Icon for Nimbostratus rankNimbostratus
Nov 03, 2005

How to ignore case

Greetings,

 

I am a frequent lurker of the devcentral forums.

 

 

Does anyone know of a way to parse a payload and ignore case? My challange is that I am dealing with a proprietary protocol and the developers could care less if their commands are "update" "Update" "UPDATE" "uPdAtE" etc...

 

 

Collect the TCP data from the session

 

when CLIENT_ACCEPTED {

 

log local0. "TCP client accepted..."

 

}

 

when CLIENT_DATA

 

Parse the payload for UPDATE

 

if { [TCP:payload] contains "UPDATE" <--- make this case insensitive

 

} {

 

log local0. "found UPDATE"

 

}

 

TCP::release

 

TCP::collect

 

TCP::notify response

 

log local0. "notify response"

 

}

 

8 Replies

  • use:

     

     

    string tolower string ?first? ?last?

     

    Returns a value equal to string except that all upper (or title) case letters have been converted to lower case. If first is specified, it refers to the first char index in the string to start modifying. If last is specified, it refers to the char index in the string to stop at (inclusive). first and last may be specified as for the index method.

     

  • There are several options you can go with here. If your payload isn't too large, then you could go with the above solution of using the string tolower command

    if { [string tolower [TCP::payload]] contains "update" } {
      ...
    }

    But, for large payloads, this might require too much memory usage that you would like to give up. In that case, you could use a regular expression search

    if { [regexp {[Uu][Pp][Dd][Aa][Tt][Ee]} [TCP::payload]] == 1 } {
      ...
    }

    Another thing to consider is whether you are going to be making a lot more than one comparison. Too many regexps might cause too much CPU usage for processing, so you might want to go back to the first method, but store it in a temporary variable so you don't have to create the temporary string for each match.

    set content [string tolower [TCP::payload]]
    if { $content contains "update" } {
      ...
    } elseif { $content contains "command2" } {
      ...
    }

    Lots of options. Choose the best for your situation.

    -Joe

  • unRuleY_95363's avatar
    unRuleY_95363
    Historic F5 Account
    Ugh, try not to use regular expressions. They are a performance monster.

    You can also use the "-nocase" option to several of the string commands (like: string compare). We've also added support for this option to "string first" which is not documented on the Tcl site.

    For example:

    if { [string first -nocase "foo" [HTTP::uri]] } {...}

    This finds the first occurance of "foo" regardless of case in the uri.

    The advantage of using the -nocase option is that a copy of the string is not made, thus making it perform faster.

  • unRuleY_95363's avatar
    unRuleY_95363
    Historic F5 Account
    Well, the -nocase option is standard, just not for "string first" for some reason.
  • Joe, thanks for the warm welcome. I didn't realize that I was famous. Unfortunately, my blog has been neglected. We are in the process of creating a new site that will feature my blog among other things and will have fresh, relevent (F5), content.

     

     

    I appreciate your responses this will go a long way. This client is particularly concerned about latency. So, I will post again with results from among the various suggestions.
  • I can't wait to see your new site. Let us know when it goes live and I'll promote it from here! Also, any feedback you give will help others who are facing the same issues you are.

     

     

    Take care and keep in touch!

     

     

    -Joe
  • Lee_Orrick_5554's avatar
    Lee_Orrick_5554
    Historic F5 Account
    Just for clarity.

     

     

    Note the difference between:

     

    if { [string first -nocase [HTTP::uri] "foo"] } {...}

     

     

    which should really be:

     

    if { [string first -nocase "foo" [HTTP::uri] ] } {...}

     

     

    From TCL manual:

     

    string first string1 string2 ?startIndex?

     

    Search string2 for a sequence of characters that exactly match the characters in string1. If found, return the index of the first character in the first such match within string2. If not found, return -1. If startIndex is specified (in any of the forms accepted by the index method), then the search is constrained to start with the character in string2 specified by the index.

     

     

    I am just trying to avoid some potential confusion for future readers of this thread.