Forum Discussion

Bob_10976's avatar
Bob_10976
Icon for Nimbostratus rankNimbostratus
Mar 25, 2010

Rewrite rule not working, what am I missing?

I have this iRule that works fine, with the exception of the last entry, which I can't seem to get to take. This is assiged to our MOSS farm, so we have several web sites under one pool. I added the log entries to see if the rule was even being hit and i'm not seeing anything in the LTM's log files.

 

 

Any suggestions would be greatly appreciated.

 

 

when HTTP_REQUEST {

 

if { ([string tolower [HTTP::host]] equals "domain1.com") || ([string tolower [HTTP::host]] equals "www.domain1.com") } {

 

HTTP::respond 301 Location http://domain2.com

 

}

 

elseif { ([string tolower [HTTP::host]] equals "domain3.com") || ([string tolower [HTTP::host]] equals "www.domain3.com")} {

 

HTTP::respond 301 Location https://domain3-edit.com

 

}

 

elseif { ([string tolower [HTTP::host]] equals "www.domain4.com") } {

 

HTTP::respond 301 Location http://domain4.com/

 

}

 

elseif { ([string tolower [HTTP::host]] equals "domain5.com") } {

 

HTTP::respond 301 Location https://domain5-edit.com/

 

}

 

elseif { ([string tolower [HTTP::host]] equals "www.domain6.com") } {

 

HTTP::respond 301 Location http://domain6.com/

 

}

 

elseif { ([string tolower [HTTP::host]] equals "www.domain7.com") } {

 

HTTP::respond 301 Location http://domain7.com/

 

}

 

elseif { ([string tolower [HTTP::host]] equals "domain7.com/security") } {

 

log local0. "Host before: [HTTP::host]"

 

HTTP::respond 301 Location http://domain7.com/ciso/pages/services.aspx

 

log local0. "Host after: [HTTP::host]" }

 

 

}

 

 

Thanks,

 

Bob

9 Replies

  • Hi Bob,

    Your last check is on the HTTP::host value, but you're looking for a host and URI.

    You can use switch to do this a little cleaner and more efficiently:

     
     when HTTP_REQUEST { 
        switch "[string tolower [HTTP::host]]" { 
           "domain1.com" - 
           "www.domain1.com" { 
              HTTP::respond 301 Location "http://domain2.com 
           } 
           "domain3.com" - 
           "www.domain3.com" { 
              HTTP::respond 301 Location "https://domain3-edit.com 
           } 
           "www.domain4.com" { 
              HTTP::respond 301 Location "http://domain4.com/" 
           } 
           "domain5.com" { 
              HTTP::respond 301 Location "https://domain5-edit.com/" 
           } 
           "www.domain6.com" { 
              HTTP::respond 301 Location "http://domain6.com/" 
           } 
           "www.domain7.com" { 
              HTTP::respond 301 Location "http://domain7.com/" 
           } 
           "domain7.com" { 
              if {[string tolower [HTTP::uri]] eq "/security"}{ 
                 HTTP::respond 301 Location "http://domain7.com/"ciso/pages/services.aspx 
              } 
           } 
        } 
     } 
     

    Aaron
  • Aaron...Thanks for the quick response and that is much cleaner then what I've been doing. It worked like a charm. I'm going to be looking at some other iRules I got and see about cleaning them up as well. This way seems much easier to maintain..

     

     

    BTW..I've not seen that switch function before, where can I find more information on that?

     

     

    Thanks again..

     

    Bob
  • I forgot to ask, and I'm sure I can do this a couple of ways but since were being so clean I'd like to keep it that way.

     

     

    The domain7 that I was looking to match both host and uri, I have other uri's on that same host that I have to redirect. Do I create a whole new entry, basically the same thing you gave me before or do I use an elseif in there, or is there a way to stack them like you did with the first entry using a "-"?

     

     

     

    Thanks

     

    Bob

     

     

     

    when HTTP_REQUEST {

     

    switch "[string tolower [HTTP::host]]" {

     

    "domain1.com" -

     

    "www.domain1.com" {

     

    HTTP::respond 301 Location "http://domain2.com

     

    }

     

    "domain3.com" -

     

    "www.domain3.com" {

     

    HTTP::respond 301 Location "https://domain3-edit.com

     

    }

     

    "www.domain4.com" {

     

    HTTP::respond 301 Location "http://domain4.com/"

     

    }

     

    "domain5.com" {

     

    HTTP::respond 301 Location "https://domain5-edit.com/"

     

    }

     

    "www.domain6.com" {

     

    HTTP::respond 301 Location "http://domain6.com/"

     

    }

     

    "www.domain7.com" {

     

    HTTP::respond 301 Location "http://domain7.com/"

     

    }

     

    "domain7.com" {

     

    if {[string tolower [HTTP::uri]] eq "/security"}{

     

    HTTP::respond 301 Location "http://domain7.com/"ciso/pages/services.aspx

     

    }

     

    }

     

    }

     

    }

     

  • Here is a set of TCL man pages for the 8.4 version of TCL current iRules are based on:

    http://www.tcl.tk/man/tcl8.4/TclCmd/contents.htm

    And here is the man page for switch:

    http://www.tcl.tk/man/tcl8.4/TclCmd/switch.htm

    If I understand correctly, you can use a nested switch statement for domain7.com URI checking:

        
      when HTTP_REQUEST {  
         switch "[string tolower [HTTP::host]]" {  
            "domain1.com" -  
            "www.domain1.com" {  
               HTTP::respond 301 Location "http://domain2.com  
            }  
            "domain3.com" -  
            "www.domain3.com" {  
               HTTP::respond 301 Location "https://domain3-edit.com  
            }  
            "www.domain4.com" {  
               HTTP::respond 301 Location "http://domain4.com/"  
            }  
            "domain5.com" {  
               HTTP::respond 301 Location "https://domain5-edit.com/"  
            }  
            "www.domain6.com" {  
               HTTP::respond 301 Location "http://domain6.com/"  
            }  
            "www.domain7.com" {  
               HTTP::respond 301 Location "http://domain7.com/"  
            }  
            "domain7.com" {  
               switch -glob "[string tolower [HTTP::uri]]" {  
           "/security" {  
           "/security/" -  
                      Exact match for "/security" or "/security/"  
                     HTTP::respond 301 Location "http://domain7.com/ciso/pages/services.aspx"  
                  }  
           "/urib*" {  
                      URI starts with "/urib"  
                     HTTP::respond 301 Location "http://domain7.com/ciso/pages/urib.aspx"  
                  }  
           "*uric" {  
                      URI ends with "uric"  
                     HTTP::respond 301 Location "http://domain7.com/ciso/pages/uric.aspx"  
                  }  
           "*uri[d-f]" {  
                      URI ends with "urid", "urie" or "urif"  
                     HTTP::respond 301 Location "http://domain7.com/ciso/pages/uric.aspx"  
                  }  
           "*uri?" {  
                      URI ends with "uri" and any other character (which hasn't already been matched like b, c, d-f)  
                     HTTP::respond 301 Location "http://domain7.com/ciso/pages/uric.aspx"  
                  }  
               }  
            }  
            "www.domain8.com" {  
               HTTP::respond 301 Location "http://domain8.com/"  
            }  
            default {  
                Take some default action? 
            }  
         }  
      }  
        
        

    Note the -glob flag on the URI checking. This allows you to use string patterns in the switch cases as defined in the 'string match' man page:

    http://www.tcl.tk/man/tcl8.4/TclCmd/string.htmM35

    string match ?-nocase? pattern string

    See if pattern matches string; return 1 if it does, 0 if it doesn't. If -nocase is specified, then the pattern attempts to match against the string in a case insensitive manner. For the two strings to match, their contents must be identical except that the following special sequences may appear in pattern:

    *

    Matches any sequence of characters in string, including a null string.

    ?

    Matches any single character in string.

    [chars]

    Matches any character in the set given by chars. If a sequence of the form x-y appears in chars, then any character between x and y, inclusive, will match. When used with -nocase, the end points of the range are converted to lower case first. Whereas {[A-z]} matches '_' when matching case-sensitively ('_' falls between the 'Z' and 'a'), with -nocase this is considered like {[A-Za-z]} (and probably what was meant in the first place).

    \x

    Matches the single character x. This provides a way of avoiding the special interpretation of the characters *?[]\ in pattern.

    Aaron
  • Wow..sweet, I did actually get it to work using elseif statements, but I like how you've done this. The only question I have is how do you break out of the -glob flag. Is it as simple as what I did when I added domain8.com at the bottom, or should I adding those type of domains before the -glob flag?

     

     

     

    when HTTP_REQUEST {

     

    switch "[string tolower [HTTP::host]]" {

     

    "domain1.com" -

     

    "www.domain1.com" {

     

    HTTP::respond 301 Location "http://domain2.com

     

    }

     

    "domain3.com" -

     

    "www.domain3.com" {

     

    HTTP::respond 301 Location "https://domain3-edit.com

     

    }

     

    "www.domain4.com" {

     

    HTTP::respond 301 Location "http://domain4.com/"

     

    }

     

    "domain5.com" {

     

    HTTP::respond 301 Location "https://domain5-edit.com/"

     

    }

     

    "www.domain6.com" {

     

    HTTP::respond 301 Location "http://domain6.com/"

     

    }

     

    "www.domain7.com" {

     

    HTTP::respond 301 Location "http://domain7.com/"

     

    }

     

    "domain7.com" {

     

    switch -glob "[string tolower [HTTP::uri]]" {

     

    "/security" {

     

    "/security/" -

     

    Exact match for "/security" or "/security/"

     

    HTTP::respond 301 Location "http://domain7.com/ciso/pages/services.aspx"

     

    }

     

    "/urib*" {

     

    URI starts with "/urib"

     

    HTTP::respond 301 Location "http://domain7.com/ciso/pages/urib.aspx"

     

    }

     

    "*uric" {

     

    URI ends with "uric"

     

    HTTP::respond 301 Location "http://domain7.com/ciso/pages/uric.aspx"

     

    }

     

    "*uri[d-f]" {

     

    URI ends with "urid", "urie" or "urif"

     

    HTTP::respond 301 Location "http://domain7.com/ciso/pages/uric.aspx"

     

    }

     

    "*uri?" {

     

    URI ends with "uri" and any other character (which hasn't already been matched like b, c, d-f)

     

    HTTP::respond 301 Location "http://domain7.com/ciso/pages/uric.aspx"

     

    }

     

    "www.domain8.com" {

     

    HTTP::respond 301 Location "http://domain8.com/"

     

    }

     

     

    }

     

    }

     

    }

     

    }

     

     

    Thanks again this his very helpful...

     

     

    Bob
  • Not sure how you get the rule in there with all the formatting in place but I can't seem to figure that one out..sorry it so flat, I'm sure that doesn't make it any easier for you to read...

     

     

    Bob
  • I added a domain8 and a default case to the post above.

     

     

    You can use [ code ] [ / code ] tags without the spaces to preserve formatting and prevent emoticons.

     

     

    Aaron
  • Hey bob, check out the iRules wiki on "switch" I found it to be a little more reader friendly as they apply situations to the F5...

     

     

    http://devcentral.f5.com/Default.aspx?tabid=63&articleType=ArticleView&articleId=129

     

     

    Read up on all the wikis while you're at it... lots of info in there man..
  • Thanks a lot for the help on this, I really appreciate it!

     

     

    Bob