Forum Discussion

Richard_Kim_270's avatar
Richard_Kim_270
Icon for Nimbostratus rankNimbostratus
Jan 11, 2007

iRule for starts with "reports/" data group?

 

I'm looking for an iRule that will redirect the request to a pool if the URL contains a "/reports/* in the URL path. Currently I am using:

 

 

when HTTP_REQUEST {

 

if { [matchclass [HTTP::uri] contains $::Report_Strings] } {

 

pool RP_pool_1

 

}

 

}

 

 

 

Report_strings is the data group and has several specific paths that I am adding manually every time we discovery a new report path. There has to be an easier way! Also, I would like the request to ignore Uppercase/lower case so it is not case sensitive. Thanks.

6 Replies

  • Try this:

    
    when HTTP_REQUEST {
      if { [matchclass [string tolower [HTTP::uri]] contains $::Report_Strings] } {
        pool RP_pool_1
      }
    }
  •  

    Does the string "string tolower" converts the request to all lowercase letters? Therefore my strings in the Data Group "Report_Strings" should also be in lower case?
  • yes & yes. Conversely, you can use string toupper if you want to go that route.
  • Yes, the "strings tolower" built-in TCL command will convert the string to lower case. So, if you "string tolower" the HTTP::uri you will want all your strings in your Report_Strings data group to be lower case.

    But if all you want to do is to match all uri's that start with "/reports/" then why don't you just use a simple string comparison with the starts_with operator?

    when HTTP_REQUEST {
      if { [string tolower [HTTP::uri]] starts_with "/reports/" } {
        pool RP_pool_1
      }
    }

    -or- you could use a switch statement and string globbing

    when HTTP_REQUEST {
      switch -glob [string tolower [HTTP::uri]] {
        "/reports/*" {
          pool RP_pool_1
        }
      }
    }

    -Joe
  • That should work for you. The only problem with the contains operator is that it acts like "*string*" so for report the following urls would work

    http://host/report/foo

    http://host/foo/report

    http://host/foo/fooreport

    http://host/foo/bar?report=1

    If you just want uris that start with "/report", "/admin", "/reports", you might want to use the starts_with operator as opposed to using contains.

    Also, If you only have a handful of strings, a data group might not be the easiest to manage. You can expand my above switch statement to the following:

    when HTTP_REQUEST {
      switch -glob [string tolower [HTTP::uri]] {
        "/admin/*" -
        "/report/*" -
        "/reports/*" {
          pool RP_pool_1
        }
      }
    }

    This will only match uri's that start with the strings in your report class.

    But, if you really do want to just search for that string anywhere in the uri you could also do this with a switch statement

    when HTTP_REQUEST {
      switch -glob [string tolower [HTTP::uri]] {
        "*/admin/*" -
        "*/report/*" -
        "*/reports/*" {
          pool RP_pool_1
        }
      }
    }

    If data groups work for you and you want to make sure the strings are at the beginning of the uri I'd suggest you change it to this:

    when CLIENT_ACCEPTED { 
      set default_pool [LB::server pool]
    }
    when HTTP_REQUEST {
      if { [matchclass [string tolower [HTTP::uri]] starts_with $::Report_strings_matchclass] } {
        pool RP_pool_1
      } else {
        pool $default_pool
      }
    }

    and make sure your Reports_strings_matchclass datagroup looks like this:

    /admin/

    /report/

    /reports/

    One other thing to note. I'm not sure it's needed for you to manually assign the pool with the value of the [LB::server pool]. If it's the default pool in the vs profile, then why set it again? It's already set to that value.

    So many ways to do the same thing. You decide which is best for you.

    -Joe
  •  

     

    One other thing to note. I'm not sure it's needed for you to manually assign the pool with the value of the [LB::server pool]. If it's the default pool in the vs profile, then why set it again? It's already set to that value.

     

     

    So many ways to do the same thing. You decide which is best for you.

     

     

    -Joe

     

     

     

    I read somewhere on this forumn that even if a default pool is specified that in some cases it may still default to the last pool in your iRule. Of course they then talked about other stuff that was beyond me so I decided to take a safer approach. But if it is working as intended than I can safetly remove the offending segment. Thanks!