Forum Discussion

Moe_Jartin's avatar
Jan 22, 2010

How to match just / uri????

I have the following irule:

 

 

when HTTP_REQUEST {

 

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

 

/services* {

 

pool pool_beta-dev.blah.org_SERVICES

 

}

 

/access* -

 

/auth* {

 

pool pool_beta-dev.blah.org_AUTH

 

}

 

/home* -

 

/shared* {

 

pool pool_beta-dev.blah.org_SHARED

 

}

 

/ -

 

/main* -

 

/member* -

 

/legal* -

 

/manual* -

 

/platform* -

 

/resources* -

 

/search* {

 

pool pool_beta-dev.blah.org_SEARCH

 

}

 

/notebook* {

 

pool pool_beta-dev.blah.org_NOTEBOOK

 

}

 

/error* {

 

pool pool_beta-dev.blah.org_ERROR

 

}

 

/sys-policy* {

 

pool pool_beta-dev.blah.org_POLICY

 

}

 

default {

 

HTTP::redirect http://beta-dev.blah.org/error/ui?code=404

 

}

 

}

 

}

 

 

 

 

Notice the match for just forward slash (/) going to the SEARCH pool. I can not get any request for just / to go to that pool. They just hit the default at the bottom and get redirected to the error page. Is there some secret to matchig just forward slash? Strange thing is, I have a nearly identical irule on another LTM and it matches on just / fine. HELP!!???!!!

10 Replies

  • Hi Joe,

    Have you tried using quotes

    I.E

     
     . 
     . 
     . 
     "" - 
     "/main*" - 
     "/member*" - 
     "/legal*" - 
     "/manual*" - 
     "/platform*" - 
     "/resources*" - 
     "/search*" { 
     pool pool_beta-dev.blah.org_SEARCH 
     } 
     . 
     . 
     . 
     

    I hope this helps

    Bhattman

  • Doesn't that make it act like an equals? effectively removing my wildcards??
  • I tried it with quotes and stil the same behavior. Why is it NOT matching?????
  • hoolio's avatar
    hoolio
    Icon for Cirrostratus rankCirrostratus
    I'm not sure quotes will make a difference for switch cases:

     

     

    % switch / {

     

    a { puts "matched A" }

     

    b { puts "matched B" }

     

    / { puts "matched slash" }

     

    default { puts "no match" }

     

    }

     

     

    matched slash

     

     

    Can you add logging to the rule and see which case is actually being matched? If the match is made correctly, but the wrong pool is used, can you add a OneConnect profile to the VIP and retest? For details on this, you can check this page:

     

     

    http://devcentral.f5.com/wiki/default.aspx/AdvDesignConfig/oneconnect.html

     

     

    Aaron

     

  • So after turning on some logging and looking at the HTTP headers in the browser i discovered that it actually WAS matching on just the "/" but then the server was redirecting with some params so it was trying to go to /?lang=eng, which of course was NOT being matched by just /. So I had to add another match string for "/?*". Of course the ? is a regex special character so I had to escape it, so then it looked like "/\?*" but that wasn't matching for some reason either. After a bit of digging I found that I had to double escape the ? for some reason????? So the final match strings looks like:

     

     

    when HTTP_REQUEST {

     

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

     

    /services* {

     

    pool pool_beta-dev.blah.org_SERVICES

     

    }

     

    .......

     

    / -

     

    /\\?*

     

    /main* -

     

    /member* -

     

    /legal* -

     

    /manual* -

     

    /platform* -

     

    /resources* -

     

    /search* {

     

    pool pool_beta-dev.blah.org_SEARCH

     

    }

     

    .........

     

    default {

     

    HTTP::redirect http://beta-dev.blah.org/error/ui?code=404

     

    }

     

    }

     

    }

     

     

     

    Hope that helps someone.

     

     

    One last question, why did I have to double escape the question mark?

     

     

    Joe
  • hoolio's avatar
    hoolio
    Icon for Cirrostratus rankCirrostratus
    It should work with a single escaping backslash:

     
     when RULE_INIT { 
         
        set slash_string /\?param=value 
        log local0. "$slash_string: $slash_string" 
      
        switch -glob $slash_string { 
           /\?* { log local0. "matched 1" } 
           default { log local0. "no match" } 
        } 
     } 
     

    : $slash_string: /?param=value

    : matched 1

    Also, you could replace HTTP::uri with HTTP::path and then use "/" as the switch case.

    Aaron
  • Aaron,

     

     

    Thanks for your help!! For whatever reason it would not match on the single backslash and unfortunately I would probably get slapped around if I dink with the VIP again today. I will look at it again tomorrow and try some additional logging. What is the difference between HTTP::uri and HTTP::path? Seem to be the same except with HTTP::path I can actually alter the path rather than just query it.

     

     

    Thanks,

     

     

    Joe
  • hoolio's avatar
    hoolio
    Icon for Cirrostratus rankCirrostratus
    HTTP::uri returns the full URI (/path/to/file.ext?param=value) and HTTP::path returns just the path (/path/to/file.ext). For a URI of /?param=value, HTTP::path would return just /.

     

     

    For details, you can check the wiki pages:

     

     

    http://devcentral.f5.com/wiki/default.aspx/iRules/http__path

     

    http://devcentral.f5.com/wiki/default.aspx/iRules/http__uri

     

     

    Aaron
  • I have TONS of "URI Switching" iRules in my LTMs. Would HTTP::path be quicker or at least less resource-intensive? Thanks Again.
  • hoolio's avatar
    hoolio
    Icon for Cirrostratus rankCirrostratus
    I think you'd need to do some testing to find that out for your particular rules/applications. You can use the timing command to check the average CPU cycles per event: http://devcentral.f5.com/wiki/default.aspx/iRules/timing

     

     

    I don't know the inner workings for the two commands, but I'd guess that HTTP::path requires at least one more operation than HTTP::uri to parse the path from the URI. If you're checking to see if the path or URI starts with a string, I'd guess HTTP::path and HTTP::uri would take close to the same CPU cycles to do the evaluation (with HTTP::path taking just a bit more CPU time to do the extra operation). If you're doing a "contains" comparison with a URI that contains a query string, then the shorter comparison HTTP::path should be more efficient.

     

     

    Aaron