Forum Discussion

Darren_Person_2's avatar
Darren_Person_2
Icon for Nimbostratus rankNimbostratus
Nov 03, 2006

iRule URL Rewrite for Multiple domains

Can someone explain how to approach this problem?

 

 

I have multiple domains that each need to 302 redirect back to their primary's:

 

 

For example,

 

i have:

 

 

www.test.com

 

test.com

 

www.xyz.com

 

xyz.com

 

www.primary.com

 

(...)

 

 

all need to 302 redirect to

 

primary.com

 

 

Then time this by 16 different sites.

 

 

how would you approach this problem?

 

6 Replies

  • You could use a class along with the matchclass command (look in the wiki for an example on that one). Or you could use a switch statement if you want all the domains within your iRule and not externalized in a class

    when HTTP_REQUEST {
      switch [HTTP::host] {
        "www.test.com" -
        "test.com" -
        "www.xyz.com" -
        "xyz.com" - {
          HTTP::redirect "http://primary.com[HTTP::uri]"
        }
      }
    }

    Remove the "[HTTP::uri]" from the redirect if you don't want to carry on the original request with the redirect.

    If you have many addresses, it might be simpler to add them all to a class and use the matchclass command to search the class for the given host.

    -Joe
  • Hi Joe,

     

     

    Thanks for the quick reply - one follow up:

     

     

    Since we have many different sites (which have lots of redirect URL's), would you suggest using an individual class for each site, or put everything in one class?

     

     

    Also, is there a CPU cost benefit of using a class with the matchclass function? I was under the impression that matchclass is a fairly expensive operation?

     

     

    Thanks again!
  • There was a good contribution to the wiki a while back outlining general guidelines on how to write fast iRules

     

     

    http://devcentral.f5.com/Wiki/default.aspx/iRules/HowToWriteFastRules.html

     

    Click here

     

     

    It states in there that switch statements are better than matchclass for 100 items or less. While that may be true, manageability is a major issue to consider. Including everything in a class, especially when you are mapping domains to uris, is much more usable and easy to update.

     

     

    If I were you, I'd go with the class approach and either with the matchclass or findclass calls (matchclass if you just want to see if an element is present, findclass if you want to extract the element and possible other subcomponents).

     

     

    This code illustrates how you can embed domains and redirect urls into a class and access them with the findclass command:

     

     

    class domain_check {
      "www.test.com primary.com"
      "test.com primary.com"
      "www.xyz.com secondary.com"
      "xyz.com secondary.com"
    }
    --- Begin iRule ---
    when HTTP_REQUEST {
      set redir [findclass [HTTP::host] $::domain_check " "]
      if { $redir ne "" } {
        HTTP::redirect "http://$redir[HTTP::uri]"
      }
    }

     

     

    The findclass will look for the HTTP::host value and return the second token in the list item (separated by spaces).

     

     

    Your iRule remains quite simple and all your management is done within the data group.

     

     

    If you have the same domain you are mapping to, just use the matchclass which returns a boolean if a match is found.

     

     

    -Joe
  • Just as a follow up on this, for those users who are currently using the "redirect" for URLS, this is considered a bad practice for SEO.

     

    The built in redirect command defaults to a 302 redirect - for SEO, you should use 301 redirect - here is an example:

     

    http://devcentral.f5.com/Default.aspx?tabid=53&view=topic&forumid=5&postid=4317

     

    I couldn't find this thread...
  • when HTTP_REQUEST {
      if { [HTTP::uri] contains "select"  } {
        use pool web_pool_web02
      } elseif { [HTTP::uri] contains "survey"  } {
        use pool web_pool_web02
      } elseif { [HTTP::uri] contains "bcaonline"  } {
        use pool web_pool_web01
      } elseif { [HTTP::uri] contains "onlinene"  } {
        use pool web_pool_web02
      } elseif { [HTTP::uri] contains "onlinesubscadmin"  } {
        use pool web_pool_web02
      } elseif { [HTTP::uri] contains "MAILFORM"  } {
        use pool cms_saiglobal
      } elseif { [HTTP::host] contains "saiglobal.com.au"  } {
        HTTP::redirect "http://www.saiglobal.com/[HTTP::uri]"
      } elseif { ([HTTP::host] contains "sai-global.com.au") and ([HTTP::uri] contains "shop") } {
        HTTP::redirect "http://www.saiglobal.com/[HTTP::uri]"
      } elseif { [HTTP::host] contains "saiglobalinc.com"  } {
        [HTTP::redirect "http://www.saiglobal.com/[HTTP::uri]"
      } elseif { [HTTP::host] contains "qas.com.au"  } {
        HTTP::redirect "http://www.saiglobal.com/[HTTP::uri]"
      } elseif { ([HTTP::host] contains "www.standards.com.au") and ([HTTP::uri] contains "catalogue") } {
        HTTP::redirect "http://www.saiglobal.com/[HTTP::uri]"
      } elseif { ([HTTP::host] contains "cqc-sai.com") and ([HTTP::uri] contains "shop") } {
        HTTP::redirect "http://www.saiglobal.com/[HTTP::uri]"
      } elseif  { ([HTTP::host] contains "sai-global.com") and ([HTTP::uri] contains "shop") }  {
        HTTP::redirect "http://www.saiglobal.com/[HTTP::uri]"
      } else {
        use pool web_pool_shop
      }
    }

    The first few lines at the top do some load balancing to different pools.

    I then have some detections which descriminates redirects if the traffic is on specific uri eg. if the directory path is /shop and the domain name is bla bla then redirect. This has been necessary as we have a cms that handles a lot of virtual sites /directories within IIS. however, if I simply do a find and replace (something the irule editor doesn't have)

    find

    replace

    the irule says that the rule is valid, but my sites start failing.

  • I've corrected your iRule in your previous post (there were some formatting issues that caused the post to not display so I had to correct those anyway.

     

     

    When calling HTTP::redirect, you should not enclose the call in brackets. Command that you expect to issue immediately and return a value (ie, HTTP::host), you'll enclose in brackets to indicate to the TCL interpreter that that command is to be evaluated immediately. This of it like a "get" accessor command. But, for all other commands, you should not surround in brackets.

     

     

    So, I've removed the brackets from your HTTP::redirect commands which should cause the correct redirects to be sent back to the client.

     

     

    -Joe