Forum Discussion

John_Merritt_45's avatar
John_Merritt_45
Icon for Nimbostratus rankNimbostratus
Nov 06, 2006

Need help with multi domain url rewrite

I am new to the iRule world. I have multiple domains that I need to rewrite. The first group should all rewrite to the same url. However I have another domain that I want to rewrite to a second url.

 

 

Not sure where my syntax error is or if there is a better way to do this.

 

 

when HTTP_REQUEST {

 

if { switch [HTTP::host] {

 

"www.abc.com" -

 

"www.def.com" -

 

"www.ghik.com" -

 

"www.lmnop.com" - {

 

HTTP::redirect "http://www.xzy.com/content.cfm?pageid=11049]"

 

}

 

} else {

 

HTTP::host equals "order.ac,e.com" {

 

HTTP::redirect "https://catalog.acme.com"

 

}

 

}

 

}

9 Replies

  • Colin_Walker_12's avatar
    Colin_Walker_12
    Historic F5 Account
    You've got the right idea, but you can combine that logic into one switch statement.

    Try something like this:

    
    when HTTP_REQUEST {
      switch -glob [string tolower [HTTP::host] ] {
        "*abc.com" -
        "*def.com" -
        "*ghik.com" -
        "*lmnop.com" {
          HTTP::redirect "http://www.xzy.com/content.cfm?pageid=11049]"
        }
        "order.ace.com" {
          HTTP::redirect "https://catalog.acme.com"
        }
      }
    }

    This allows you to expand easily as well, by adding more domains to the list above "lmnop.com" if you need to have more perform the same action later.

    HTH,

    Colin
  • Hi Colin,

     

     

    Joe responded to a similar question I posted - can you show an example of the above using classes instead of a very large switch?

     

     

    I like the *domain.com - I didn't know you could wildcard that - very interesting. Also, goo idea to lowercase the host name - is this typically case sensitive?
  • The -glob will give you "globbing" functionality. Not quite regular expressions, but with wildcarding.

    The problem with a class approach is that you can't easily do wildcard matching so you'll have to have an entry for each possibility for the domains.

    There are two approaches to using classes with redirects.

    1) Using classes with each domain and it's redirect

    class domain_check {
      "www.abc.com http://www.xzy.com/content.cfm?pageid=11049]"
      "www.def.com http://www.xzy.com/content.cfm?pageid=11049]"
      "www.ghik.com http://www.xzy.com/content.cfm?pageid=11049]"
      "www.lmnop.com http://www.xzy.com/content.cfm?pageid=11049]"
      "order.ace.com https://catalog.acme.com" 
    }
    --- Begin iRule ---
    when HTTP_REQUEST {
      set redir [findclass [string tolower [HTTP::host]] $::domain_check " "]
      if { $redir ne "" } {
        HTTP::redirect "$redir"
      }
    }

    Or, you could use multiple classes along with the match class command and the ends_with operator to give more of a wild-card type approach

    class domain_one {
      "www.abc.com"
      "www.def.com"
      "www.ghik.com"
      "www.lmnop.com"
    }
    class domain_two {
      "order.ace.com " 
    }
    --- Begin iRule ---
    when HTTP_REQUEST {
      if { [matchclass [string tolower [HTTP::host]] ends_with $::domain_one] } {
        HTTP::redirect "http://www.xzy.com/content.cfm?pageid=11049]"
      } elseif { [matchclass [string tolower [HTTP::host]] ends_with $::domain_two] } {
        HTTP::redirect "https://catalog.acme.com"
      }
    }

    One final option would be to do a hybrid approach where you externalize the redirect urls.

    class domain_check {
      "www.abc.com 1"
      "www.def.com 1"
      "www.ghik.com 1"
      "www.lmnop.com 1"
      "order.ace.com 2" 
    }
    class redirect_urls {
      "1 http://www.xzy.com/content.cfm?pageid=11049]"
      "2 https://catalog.acme.com"
    }
    --- Begin iRule ---
    when HTTP_REQUEST {
      set redir_idx [findclass [string tolower [HTTP::host]] $::domain_check " "]
      if { $redir_idx ne "" } {
        set redir [findclass $redir_idx $::redirect_urls " "]
        if { $redir ne "" } {
          HTTP::redirect "$redir"
        }
      }
    }

    Not sure why you would want this level of indirection, but it makes it so if you need to change your redirect urls more often, you only have to change it in one place.

    As for optimization, your best bet is to go with the switch approach, then the matchclass, then the first findclass, then the last one. You determine which would work best for your situation.

    Good Luck!

    -Joe

  • Colin_Walker_12's avatar
    Colin_Walker_12
    Historic F5 Account
    To create the same type of functionality with classes, assuming you have at least 2 domains that you want redirected to each location, you'd likely want to use two seperate classes.

    You'd create one class for each destination location. I.E.:

    
    class redirect_to_abc {
      "host1.com"
      "host2.net"
      "host3.biz"
    }
    class redirect_to_xyz {
      "host10.com"
      "host9.us"
      "host8.org"
    }

    Then you'd create a rule to check to see if the incoming host was in either of those classes, along with a fallback action in case it doesn't land in either bucket.

    Something like:

    
    when HTTP_REQUEST {
      if { [matchclass [HTTP::host] ends_with $::redirect_to_abc ] } {
        HTTP::redirect http://www.abc.com
      } elseif { [matchclass [HTTP::host] ends_with $::redirect_to_xyz] } {
        HTTP::redirect http://www.xyz.com
      } else {
        pool fallback_pool
      }
    }

    As far as your other questions, the wildcard is only usable in a switch statement if you've specified glob style matching. Regarding forcing things to lowercase, it's kind of a habit, but probably wouldn't be necessary for the hostname, though it might be for the URI or many other things you may be comparing.

    HTH,

    Colin
  • I was trying to do something similar to what Joe recommended but unfortunately it does not seem to be working. I am basically trying to automatically redirect to an https page when a user goes to a specific page:

     

     

    
    class secure_pages {
      "\page1.aspx"
      "\page2.aspx"
      "\page3.aspx"
      "\page4.aspx"
    }
    when HTTP_REQUEST { 
       if { [string tolower [HTTP::host]] equals "test.mywebsite.com"}
       {                                              
         if { [matchclass [string tolower [HTTP::uri]] starts_with $::secure_pages]}
         { 
         HTTP::redirect "https://[HTTP::host][HTTP::uri]"
         }
         else
         {
         pool pool_A
         }
       }
       else
       {
         pool pool_B
       }
    }

     

     

    However when I try to use the above code, I get the following error:

     

     

    line 1: [undefined procedure: class] [class secure_pages {

     

    "\page1.aspx"

     

    "\page2.aspx"

     

    "\page3.aspx"

     

    "\page4.aspx"

     

    }]

     

     

    How do I properly add a "class" via the web GUI? Sorry if this is NEWBIE question, I am just learning iRule syntax.
  • The class section is not intended to be part of the iRule contents. It is a String Data Group. The class { ... } format is how it is stored in the bigip.conf configuration file. Remove the class section from the iRule and create a string data group titled secure_pages and your pages and you should be set.

     

     

    BTW, I would use a forward slash '/' instead of a backwards slash '\' in your class strings.

     

     

    -Joe
  • Thanks Joe, this code now correctly redirects the pages listed in my string data group "secure_pages" to a https URL:

     

     

    
    when HTTP_REQUEST { 
       if { [string tolower [HTTP::host]] equals "test.mywebsite.com"}
       {                                              
         if { [matchclass [string tolower [HTTP::uri]] starts_with $::secure_pages]}
         { 
         HTTP::redirect "https://[HTTP::host][HTTP::uri]"
         }
         else
         {
         pool pool_A
         }
       }
       else
       {
         pool pool_B
       }
    }

     

     

    Now I have another issue. I want to make sure that any pages that are NOT listed in "Secure_pages" are always treated as http (and not https). Here is our business senario:

     

     

    1) User comes to page_1 (http)

     

    2) Clicks on "login". Login is in "secure_pages" string data group. (https)

     

    3) Upon successful login we automatically redirect user to page2 (http)

     

     

    Unfortunately no matter what I try the step 3 always remains https OR it doesn't do the redirect at all. Any thoughts?
  • Or please let me know if there is a more efficient way of doing this.

     

     

    Thanks again-

     

    Steve