Forum Discussion

LeonK_146224's avatar
LeonK_146224
Icon for Nimbostratus rankNimbostratus
Mar 04, 2014

http domain redirect

Hi Guys, new to irules so need your help on how to re-write the irule to include more descriptive strings. 1: We have a simple http redirect rule that we are using that utilizes datagroup strings:

 

when HTTP_REQUEST { set redirect_domain [class match -value [string tolower [HTTP::host]] equals redirect_domain] if {$redirect_domain ne ""} { HTTP::redirect "http://$redirect_domain" } unset redirect_domain }

 

It works fine if we need only one redirect per domain, but the minute I have a more global redirect I cannot utilize more descriptive ones from that same domain: Example:

 

If I have a working: domain1.de redirect to domain.com/de-de And I want to create a new one: domain1.de/careers redirect to domain.com/de-de/careers or to any other url… it doesn’t work making the domain1.de more inclusive string hit it first. Is there any way to make sure we can do more than a single “global” redirect per rule as it is kinda binds us to waste a whole domain for a single redirect….

 

3 Replies

  • You could sort your entries in the datagroup so the more general fallbacks are last. Then you can iterate through the datagroup and exit on the first match you found.

     

    See also the examples here for a sample of how to iterate through a datagroup.

     

  • I think the general problem you're having is that you're trying to redirect on URI but only evaluating the host value. I see three possible options here:

    1. Create two separate data groups - one for URI paths and one for host values

      ltm data-group internal myhosts {
          records {
              domain1.de {
                  data domain.com
              }
              domain2.de {
                  data domain.com
              }
          }
          type string
      }
      
      ltm data-group internal myuris {
          records {
              / {
                  data /de-de
              }
              /careers {
                  data /de-de/careers
              }
          }
          type string
      }
      
      when HTTP_REQUEST {
          set myhost [class match -value [string tolower [HTTP::host]] equals myhosts]
          set myuri [class match -value [string tolower [HTTP::uri]] starts_with myuris]
      
          set redirect 0
          if { $myhost ne "" } { 
              set redirect 1 
          } else {
              set myhost [HTTP::host]
          }
          if { $myuri ne "" } { 
              set redirect 1    
          } else {
              set myuri [HTTP::uri]
          }
      
          if { $redirect } {
              HTTP::redirect "http://${myhost}${myuri}"
          }    
      }
      
    2. Create a single data group that incorporates host and URI

      ltm data-group internal mypaths {
          records {
              domain1.de/ {
                  data domain.com/de-de
              }
              domain1.de/careers {
                  data domain.com/de-de/careers
              }
          }
          type string
      }
      
      when HTTP_REQUEST {
          set mypath [class match -value [string tolower [HTTP::host][HTTP::uri]] starts_with mypaths]
      
          if { $mypath ne "" } {
              HTTP::redirect "http://$mypath"
          }
      }
      
    3. Assuming the host is only going to change between a very small set of values, just build a data group for URIs

      when HTTP_REQUEST {
          switch [string tolower [HTTP::host]] {
              "domain1.de" -
              "domain2.de" {
                  HTTP::redirect "http://domain.com[HTTP::uri]"
              }
          }
      
          set myuri [class match -value [string tolower [HTTP::uri]] starts_with myuris]
          if { $myuri ne "" } {
              HTTP::redirect "http://[HTTP::host]${myuri}"
          }
      }
      

    Arguably I think the third option would be the easiest to manage, with option 2 being the most difficult.

  • you mean myhosts ? or myhost is an actual irule recognized command?

    I do mean "myhost".

    set myhost [class match -value [string tolower [HTTP::host]] equals myhosts]
    
    set redirect 0
    if { $myhost ne "" } { 
        set redirect 1 
    } else {
        set myhost [HTTP::host]
    }
    

    If the class match returns a value and sets the myhost variable, then we simply set the redirect flag. Otherwise, we set the myhost variable to the actual host [HTTP::host]. In either case, the myhost variable contains a value in case the redirect flag is set and a redirect is issued.

    Arguably option 2 will be the most difficult, given that your single data group may have MANY items to manage. Here's another option that combines options 1 and 3:

    when HTTP_REQUEST {
        set myhost [class match -value [string tolower [HTTP::host]] starts_with myhosts]
        if { $myhost ne "" } {
            HTTP::redirect "http://${myhost}[HTTP::uri]"
        }
    
        set myuri [class match -value [string tolower [HTTP::uri]] starts_with myuris]
        if { $myuri ne "" } {
            HTTP::redirect "http://[HTTP::host]${myuri}"
        }
    }
    

    This will issue an initial redirect based on the host name, and then another based on the URI.