For more information regarding the security incident at F5, the actions we are taking to address it, and our ongoing efforts to protect our customers, click here.

Forum Discussion

Daniel_Ma_23954's avatar
Daniel_Ma_23954
Icon for Nimbostratus rankNimbostratus
Feb 09, 2016

Redirect both host and path via iRules

I"m fairly new to using iRules and writing redirects, but currently I have a redirect in place that does http to https redirect via the switch parameter for different host names, see below.

when HTTP_REQUEST {
switch -glob [string tolower [HTTP::host]] {
"abc.com" - 
    "www.abc.com" {
        HTTP::redirect http://abc.123.com
    }
"def.com" -
    "www.def.com" {
               HTTP::redirect https://www.def.com[HTTP::uri]
    } 
    default {
             reject
    }     
}
}

But now, I need to add an uri/path redirect for for example:

def.com/example to https://www.def.com/site1/example

What would be the best way to accomplish this?

6 Replies

  • Hi Daniel,

    you can add leadings parts whenever you want...

    when HTTP_REQUEST {
        switch -glob [string tolower [HTTP::host]] {
        "abc.com" - 
            "www.abc.com" {
                HTTP::redirect http://abc.123.com
            }
        "def.com" -
            "www.def.com" {
                HTTP::redirect https://www.def.com/site1[HTTP::uri]
            } 
            default {
                reject
            }     
        }
    }
    

    Note:

    [HTTP::uri]
    always starts with an
    /
    , so you don't need to explicitly add a slash.

    Cheers, Kai

  • If it's just a few conditions you could reasonably nest switch statements:

    when HTTP_REQUEST {
        switch -glob [string tolower [HTTP::host]] {
            "abc.com" - 
            "www.abc.com" {
                HTTP::redirect http://abc.123.com
            }
            "def.com" -
            "www.def.com" {
                switch -glob [string tolower [HTTP::uri]] {
                    "/example*" {
                        HTTP::redirect "https://www.def.com/site1/example"
                    }
                    default { 
                        HTTP::redirect https://www.def.com[HTTP::uri]
                    }
                }
            } 
            default {
                reject
            }     
        }
    }
    
  • Thank you both for the suggestions. I'm going to try the nested switch statement later tonight. Will let you guys know if I encounter any issues.

     

  • The nested switch statements seems to be working correctly, as all the conditions are redirecting to the correct https URLs when it's a http request.

     

    However, in my case, I also need to redirect those same conditions when it's a https request. Below is what I have so far:

     

    when HTTP_REQUEST {
        switch -glob [string tolower [HTTP::uri]] {
        "/example" {
            HTTP::redirect "/site1/example"
        }
        "/example2" {
            HTTP::redirect "/site2/example"
        }
        default {
                reject
                }
    }
        }

    In the above code, I'm having some issues with the default. I've tried using reject and leaving it blank, neither seems to work properly. The default should just go to the main site. How can I accomplish this?

     

    Thanks again for the help

     

  • Hi Daniel,

    the

    [switch]
    "default" or
    [if]
    "else" conditions are both optional. You can either leave them empty, but you can also remove the default/else conditions if you like. The outcome would be exactly the same. But I personaly tend to keep those condition for better visibility and add a meaningful comment to it...

    when HTTP_REQUEST {
        switch -exact -- [string tolower [HTTP::host]] {
            "abc.com" - 
            "www.abc.com" {
                HTTP::redirect http://abc.123.com
            }
            "def.com" -
            "www.def.com" {
                switch -exact -- [string tolower [HTTP::uri]] {
                    "/example" {
                        HTTP::redirect "/site1/example"
                    }
                    "/example2" {
                        HTTP::redirect "/site2/example"
                    }
                    default {
                         Forward to default pool
                    }
                }
            } 
            default {
                reject
            }
        }
    }
    

    Note: You should use

    -glob
    only if you need to match certain single charcter wildcard
    ?
    or general wildcards
    *
    . If matching conditions without wildcards, then
    -exact
    would be the better choice in terms of performance.

    Note: If you need different rulesets for HTTP and HTTPS access, then it would be more effective to have two independent iRules. Well, if the differences are not that much, then you could also include contitions to make decission based on the accessed protocol, but its those conditions add a slightly overhead to your CPU. But on the otherhand may be reduce the administrative overhead to maintain the two almost identical iRules.

    Note: Your Datagroup approach should be fine. Datagroups are easier to manage for iRule startes, since they don't require you to have a deep iRule knowledge for daily changes.

    Note: When testing/changing iRules, then always keep in mind, that iRules changes are only become effective for new TCP connections. I guess the trouble of your "default" condition experiments may be the result of keep- alive TCP connections?

    Cheers, Kai