Forum Discussion

mike_gatti_6169's avatar
mike_gatti_6169
Icon for Nimbostratus rankNimbostratus
May 17, 2007

Using array/class to define veriable and use for redirect

I have been trying to use an array or class to define a variable that will be used for a redirect. The iRule that I have created (and not working) is:

 

 

when RULE_INIT {

 

array set sites {

 

/site1

 

/site2

 

}

 

}

 

when HTTP_REQUEST {

 

if { [HTTP::uri] starts_with $::sites] } {

 

HTTP::redirect "http://www.domain.com/global/[string range [HTTP::uri] 1 end]"

 

}

 

elseif { [HTTP::uri] starts_with "/global" } {

 

use pool site_pool

 

}

 

}

 

 

I am new to TCL and not sure if this is correct.

 

----------------------------------------------------

 

I also tried to use class and got a syntax error.

 

 

when RULE_INIT {

 

class sites {

 

“/site1”

 

“/site2”

 

}

 

}

 

when HTTP_REQUEST {

 

if { [HTTP::uri] starts_with $::sites] } {

 

HTTP::redirect "http://www.domain.com/global/[string range [HTTP::uri] 1 end]"

 

}

 

elseif { [HTTP::uri] starts_with "/global" } {

 

use pool site_pool

 

}

 

}

 

 

Trying this I received a syntax error:

 

 

[undefined procedure: class] [class sites {

 

“/site1”

 

“/site2”

 

}

 

 

 

Any help is very welcome.

 

 

Thanks

 

Mike

6 Replies

  • Some additional information,

     

    I am getting the following error logged:

     

     

    - can't read "::sites": variable is array

     

     

  • A couple of common mistakes.

     

     

    1. in your first if statement, you are comparing a string "[HTTP::uri]" with an array "sites". If you want to compare for a string's existence within a list of items, you'll have to use our "matchclass" command. Also, if you are hand-rolling the list, it needs to be a TCL list, not an array.

     

     

    when RULE_INIT {
      set sites [list \
        "/site1" \
        "/site2" \
    ]
    }
    when HTTP_REQUEST {
      if { [matchclass [HTTP::uri] starts_with $::sites] } {
        HTTP::redirect "http://www.domain.com/global/[string range [HTTP::uri] 1 end]"
      } elseif { [HTTP::uri starts_with "/global" } {
        pool site_pool
      }
    }

     

     

    2. In your second code sample you are defining the class in the iRule. The "class ..." code that is often posted to these forums is the internal format of the data group (or class) from within the internal configuration. You'll need to define this as a data group within the iRules section of the GUI.

     

     

    Now, after all that is said, for small lists of items, it is much more optimal to use a switch statement like this:

     

     

    when HTTP_REQUEST {
      switch -glob [HTTP::uri] {
        "/site1*" -
        "/site2*" {
          HTTP::redirect "http://www.domain.com/global/[string range [HTTP::uri] 1 end]"
        }
        "/global*" {
          pool site_pool
        }
      }
    }

     

     

    -Joe
  • 1st, thanks much for the help,

     

     

    I am using the 1st option since the list will be pretty big. In testing the rule I get the following error logged. I tried reading up and playing around with the rule but didn't get very far. This is the error:

     

     

    TCL error: can't set "sites": variable is array while executing "set sites [ list \ "/site1" \ "/site2" \ ]"

     

     

    her is the rule as it stands now.

     

     

    when RULE_INIT {

     

    set sites [ list \

     

    "/site1" \

     

    "/site2" \

     

    ]

     

    }

     

    when HTTP_REQUEST {

     

    if { [matchclass [HTTP::uri] starts_with $::sites] } {

     

    HTTP::redirect "http://www.domain.com/global/[string range [HTTP::uri] 1 end]"

     

    }

     

    elseif { [HTTP::uri] starts_with "/global" } {

     

    use pool site_pool

     

    }

     

    }
  • Posted By andre.bentes@reallife.pt on 04/23/2009 10:36 AM

     

    how do i create an https_request and an http_request class or data group?

     

     

     

    As Joe stated above, a class/data group is not part of the iRule syntax, it is a list of items configured under the iRules/Data Groups tab in the GUI that you then use the matchclass command to match against. HTTP_REQUEST is an event that occurs in an iRule and has nothing to do with whether you use classes & the matchclass command.

     

     

    Denny

     

  • I'm not sure if this is what you are after but I have an Initialize iRule fire first (using priority) to determine if the request is https or not.

     
     when HTTP_REQUEST priority 5 { 
      
     log local0. "In Initialize" 
             if {[TCP::local_port] == 443} { 
     set ::ghttp_protocol "https\:" 
     } else { 
     set ::ghttp_protocol "http\:" 
     } 
     } 
     

    I then use the ghttp_protocol global in another iRule that does the routing.

    HTTP::redirect "$::ghttp_protocol//www.domain.com..."

    That allows me to use the inbound port to determine if the connection was secure. granted you need to make sure you only allow SSL on 443, but it works.

    Tom Schaefer