Forum Discussion

Danielseyoum's avatar
Danielseyoum
Icon for Altostratus rankAltostratus
Jul 26, 2007

Case sensitivity challenge

I have application that is case sensitive and I have to make sure the case is formated in a way the application will respond.

 

 

incoming uri:

 

/about us --> should be --> /About Us

 

/corpcomm --> should be --> /CorpComm

 

/leading the path --> should be --> /Leading the Path

 

 

The requirement is for users to type in any case format and iRule to format it in a way the app understand.....

 

 

Thanks in advance

6 Replies

  • Chris_Seymour_1's avatar
    Chris_Seymour_1
    Historic F5 Account
    Daniel,

     

     

    Perhaps a Stream related iRule or profile would do the trick.

     

     

    when HTTP_REQUEST {

     

    set uri [HTTP::uri]

     

    }

     

     

    when HTTP_REQUEST {

     

    STREAM::enable

     

    STREAM::expression {@about us@About Us@@corpcomm@CorpComm@@leading the path@Leading the Path@}

     

    }

     

     

     

    Long time no see. Hope things are well.

     

     

    chris seymour
  • Are those requests in the URI or in the payload? It's tricky, but it can be done with a lot of TCL string manipulation. I'll see what I can whip up.

     

     

    -Joe
  • It's in the uri.

     

    I tried the following and I am not sure why it's not working:

     

     

    class urimapping {

     

    "/about us"

     

    "/corpcomm"

     

    "/leading the path"

     

    }

     

    rule iRule_uri_switch {

     

    when HTTP_REQUEST {

     

    switch -glob [matchclass [string tolower [HTTP::uri]] equals $::urimapping] {

     

    "/about us" { HTTP::redirect "https://www.test.com/irj/portal/About Us"}

     

    "/corpcomm" { HTTP::redirect "https://www.test.com/irj/portal/CorpComm"}

     

    "/leading the path"{ HTTP::redirect "https://www.test.com/irj/portal/Leading the Path"}

     

    }}}

     

  • Deb_Allen_18's avatar
    Deb_Allen_18
    Historic F5 Account
    Stream profile will only work against response data, so that won't do the inbound URI re-writing you need. (But hold that thought, you might need to use it to re-write links in the response -- more on that later.)

    First, I'd assume that the URI's received by LTM have substituted %20 for the space character.

    From there, you could use the following iRule to re-write inbound URI's to the correct case with the internal path:
    class URImap {
      "about%20us About%20Us"
      "corpcomm CorpComm"
      "leading%20the%20path Leading%20the%20Path"
    }
    rule iRule_URI_mapping {
      when HTTP_REQUEST {
        set OldRootDir [string tolower [getfield [HTTP::uri] "/" 2]]
        set NewRootDir [findclass $OldDir1 $::URImap " "]
        if {$NewRootDir != ""}{
           prepend portal path to requested URI & re-write URI with proper case
          HTTP::uri /irj/portal[string map -nocase [list $OldRootDir $NewRootDir] [HTTP::uri]]
        }
      }
    }
    Here's a post on a similar topic, a few more complexities but overall similar to yours:

    http://devcentral.f5.com/Default.aspx?tabid=53&view=topic&forumid=5&postid=13912 (Click here)

    Note the details re: stream profile for payload link translation to remove the internal path references (required if your server returns absolute rather than relative links in the response):

    -- Source: /irj/portal

    -- Target:

    and also more logic to re-write redirects containing the internal path to the external presentation.

    HTH

    /deb

  • Thanks for the guidance....

     

     

    I am getting the following error while creating the rule:

     

    line 7: [string map list should have an even number of elements] [-nocase]
  • Remove the "-nocase" flag as that isn't supported in iRules.

     

     

    Here's an alternate solution that will extract all space delimited tokens in the first path section of the URI and will convert the first character in each token to upper case.

     

     

    when HTTP_REQUEST {
      set new_uri "/"
      set args [split [string map { "%20" " " } [lindex [split [HTTP::uri] "/"] 1]] " "]
      for {set i 0} {$i < [llength $args]} {incr i} {
        set arg [lindex $args $i]
        if { $arg ne "" } {
          set CamelCaseToken [string replace $arg 0 0 [string toupper [string range $arg 0 0]]]
          if { $new_uri eq "/" } {
            set new_uri "${new_uri}${CamelCaseToken}"
          } else {
            set new_uri "${new_uri}%20${CamelCaseToken}"
          }
        } else {
          set new_uri "${new_uri}%20"
        }
      }
      HTTP::uri $new_uri
    }

     

     

    This iRule will ignore any part of the path past the first directory (since that's what you gave in your example (from the lindex in the 2nd line).

     

     

    Examples

     

    http://www.foo.com/hi there -> http://www.foo.com/%20Hi%20There

     

    http://www.foo.com/how are you -> http://www.foo.com/How%20Are%20%20You

     

     

     

    Now, if you want to support sub directories, you'll have to not just extract the first element of the path, but split the path apart and then process each section.

     

     

    This code will work with multiple paths and capitalize all first words (delimited by spaces) in all directories in the URI. I've also added a check for special characters that you do not want capitalized (since your original post had one)

     

     

    when HTTP_REQUEST {
      set new_uri ""
       Split the URI into it's directories
      set dirs [split [HTTP::uri] "/"]
       Loop over all the directories
      for {set i 0} {$i < [llength $dirs]} {incr i} {
        set dir [lindex $dirs $i]
        if { $dir ne "" } {
           Convert all %20's into Spaces, and then split by that space
           If we kept %20s the split would return a bunch of empty elements
          set args [split [string map { "%20" " " } $dir]]
          set new_sub_dir ""
          set content_added 0
           Loop over all the different words in each directory
          for {set j 0} {$j < [llength $args]} {incr j} {
            set arg [lindex $args $j]
              if { $arg ne "" } {
               Check for special words that you don't want capitolized
              switch $arg {
                "the" -
                "of" {
                  set CamelCaseToken $arg
                }
                default {
                  set CamelCaseToken [string replace $arg 0 0 [string toupper [string range $arg 0 0]]]
                }
              }
              if { $content_added eq 0 } {
                set new_sub_dir "${new_sub_dir}${CamelCaseToken}"
              } else {
                set new_sub_dir "${new_sub_dir}%20${CamelCaseToken}"
              }
              set content_added 1
            } else {
              set new_sub_dir "${new_sub_dir}%20"
            }
          }
          set new_uri "${new_uri}/${new_sub_dir}"
        }
      }
      HTTP::uri $new_uri
    }

     

     

    Examples:

     

     

    http://www.foo.com/hi there/how are you

     

    -> http://www.foo.com/Hi%20There/How%20Are%20You

     

    http://www.foo.com/howdypartner/ its time to party

     

    -> http://www.foo.com/Howdypartner/%20Its%20Time%20To%20Party

     

    http://www.foo.com/welcome to the party

     

    -> http://www.foo.com/Welcome%20To%20the%20Party

     

     

     

    Hope this helps...

     

     

    -Joe