Forum Discussion

dgloff_22332's avatar
dgloff_22332
Icon for Nimbostratus rankNimbostratus
Sep 20, 2012

switch used for string replacement skipping one case

I have to do a redirect from default.asp and default.aspx in any path, to just the path (with no filename), with a few exceptions. Initially, I had the following iRule, which worked fine:

 

when HTTP_REQUEST {

 

if { [string tolower [HTTP::path]] contains "/accountants" } {

 

return

 

}

 

elseif { [string tolower [HTTP::path]] contains "/businesspartners" } {

 

return

 

}

 

elseif { [string tolower [HTTP::path]] contains "/product/health-insurance" } {

 

return

 

}

 

elseif { [string tolower [HTTP::path]] contains "/default.aspx" } {

 

set replaceURI [string map [list /default.aspx /] [HTTP::path]]

 

HTTP::respond 301 Location "$replaceURI"

 

}

 

elseif { [string tolower [HTTP::path]] contains "/default.asp" } {

 

set replaceURI [string map [list /default.asp /] [HTTP::path]]

 

HTTP::respond 301 Location "$replaceURI"

 

}

 

}

 

 

However, when time came to add another exception, I decided to rewrite it into a switch statement. I converted the above into:

 

when HTTP_REQUEST {

 

switch -glob [string tolower [HTTP::path]] {

 

"/accountants/*" {

 

return

 

}

 

"/businesspartners/*" {

 

return

 

}

 

"/product/health-insurance/*" {

 

return

 

}

 

"/helpkb/*" {

 

return

 

}

 

"*/default.aspx" {

 

set replaceURI [string map [list /default.aspx /] [HTTP::path]]

 

HTTP::respond 301 Location "$replaceURI"

 

}

 

"*/default.asp" {

 

set replaceURI [string map [list /default.asp /] [HTTP::path]]

 

HTTP::respond 301 Location "$replaceURI"

 

}

 

}

 

}

 

 

Now, it works halfway. when going to anything/default.asp, I get correctly redirected to /anything/. However, when going to anything/default.aspx, I get redirected to /anything/x, which doesn't exist. So it appears my last case is taking precedence over the one above it. Anybody know how to clean this up and make it work again, or do I just have to add another elseif to my original rule?

 

 

  • My best guess is that the second to last section is not being skipped but that you are falling through and matching both cases. "http://www.example.com/default.aspx" is first matching "*/default.aspx" and then matching "*/default.asp" overwriting your previous changes to replaceURI. You can either get more specific with the match expressions (which I'm no pro at, haven't done anything beyond simple switches in TCL) or you can wrap the logic on the last case with an if checking to see if replaceURI is null or has value. If null, continue, otherwise do nothing.

     

     

    Might be worth the "if" approach just to determine if this is the problem and then you can clean up the switch after. You can also take advantage of the fall through to shorten up the first few cases into:

     

     

    "/accountants/*"

     

    "/businesspartners/*"

     

    "/product/health-insurance/*"

     

    "/helpkb/*" {

     

    return

     

    }

     

     

    A match on any of them would result in the return statement being executed.
  • Posted By Kevin Stewart on 09/21/2012 09:39 AM

     

    Your code works on 11.2.

     

     

    What version are you running?

     

     

    We're on 9.4.8.

     

  • I don't have a 9.x box to test with, but I concur with Brian about switching back to an 'if' syntax. The good news is that you can verifiably use the switch syntax when/if you upgrade!!

     

  • Think I found the issue. At one point I had the .aspx and .asp portions of the rule in the incorrect order, and since this is a 301 and not a 302, my browser was caching the permanent redirect and not even trying to reach the page. I discovered this because I was still getting redirected even when the iRule wasn't in place.

     

     

    Just tested it as in my OP, and it's working now (in several different browsers). I was not able to collapse it into the short form:

     

     

    "/accountants/*"

     

    "/businesspartners/*"

     

    "/product/health-insurance/*"

     

    "/helpkb/*" {

     

    return

     

    }

     

     

    as it throws an error every other line when I attempt to save. That might be a newer function of 10.x or 11.x. No worries, I'm fine with the separate listings. Thanks for the help guys!
  • To fall through, you need a dash, so the below should work:

    
    "/accountants/*" -
    "/businesspartners/*" -
    "/product/health-insurance/*" -
    "/helpkb/*" {
    return
    }
    default {
    something else
    }