Forum Discussion

sbrudolf1_14757's avatar
sbrudolf1_14757
Icon for Nimbostratus rankNimbostratus
May 22, 2014

Trouble with Exclusion URI iRule

I am trying to write an iRule that disabled APM if it see's a uri and does not see a session already exists. I have a working iRule of the opposite but i can't seem to get this working properly. Did i put the not (!) in the wrong place?

            when HTTP_REQUEST {
    if { ( ![HTTP::cookie exists MRHSession] ) and ( [string tolower [HTTP::uri]] starts_with "/uri1") } {
        ACCESS::disable
    } else {
        ACCESS::enable
        return
    }
}text
  • Your latest iRule contains a capital letter in your match string. It'll never match since you are converting to lower case before comparison.

     

  • Try this:

    when HTTP_REQUEST {
        if { ( [string tolower [HTTP::uri]] starts_with "/uri1" ) and not ( [HTTP::cookie exists MRHSession] ) } {
            ACCESS::disable
        } else {
            ACCESS::enable
            return
        } 
    }
    
  • That works great, i ran into another issue though. For some reason, i can only enter one directory into the "/uri1". EX: If i enter starts_with "/helpdesk" Then anything behind that directory won't get APM as expected. If i enter "/helpdesk/webobjects" i would expect everything behind that directory not to get APM as long as there was no session cookie. For some reason, it is still getting APM.

     

    I have verified with with the session cookie portion missing from the script too. A bug maybe? or is that the expected behavior.

     

  • Try this instead

    
    when HTTP_REQUEST {
        if { ( [string tolower [HTTP::uri]] starts_with /uri1* ) and not ( [HTTP::cookie exists MRHSession] ) } {
            ACCESS::disable
        } else {
            ACCESS::enable
            return
        } 
    }
    

    or try this using the sexy switch instead of if. It is way hotter and more performant

    
    switch -glob [string tolower [HTTP::uri]] {
       /uri1* { if { [HTTP::cookie exists MRHSession] } { 
                   ACCESS::enable
                   return
                } else {
                   ACCESS::disable
                }
              }
    }
    

    You could also swith the if to the negative/unless form if it is logically needed in the switch

    Hope this helps

  • I understand the switch, the problem is i can't just a specific URI. The below command won't work at all unless i take out the /webobjects portion. Then it works.

    when HTTP_REQUEST {
        if { ( [string tolower [HTTP::uri]] starts_with "/helpdesk/webobjects" ) and not ( [HTTP::cookie exists MRHSession] ) } {
            ACCESS::disable
        } else {
            ACCESS::enable
            return
        } 
    }
    
  • Can you elaborate on what you mean or need when you say you can only enter one directory? I re-read your previous comment that said,

    "i ran into another issue though. For some reason, i can only enter one directory into the "/uri1". EX: If i enter starts_with "/helpdesk" Then anything behind that directory won't get APM as expected. If i enter "/helpdesk/webobjects" i would expect everything behind that directory not to get APM as long as there was no session cookie. For some reason, it is still getting APM."

    Are you trying to match multiple URI prefixes and for each one check for the cookie? or are you just trying to do one single URI prefix with a subdirectory under it?

    If you just want one URI prefix but to allow any characters to the right of that URI prefix to be included then the key is the trailing asterisk and using a -glob in a switch

    If you just want to be able to check multiple different URI prefixes then you can just add as statements into the switch like below

    
    switch -glob [string tolower [HTTP::uri]] {
       /uri1* { if { [HTTP::cookie exists MRHSession] } { 
                   ACCESS::enable
                   return
                } else {
                   ACCESS::disable
                }
              }
        /helpdesk* { if { [HTTP::cookie exists MRHSession] } { 
                   ACCESS::enable
                   return
                 } else {
                   ACCESS::disable
                 }
               }
        /blah* { if { [HTTP::cookie exists MRHSession] } { 
                   ACCESS::enable
                   return
                 } else {
                   ACCESS::disable
                 }
               }
         default {
           ACCESS::disable
           return
         }
    }
    

    FYI the default block is what happens if the inbound URI does not match any of your URI prefix's. A return will just conclude the irule and you might want to set a default ACCESS action to be either disable or enable.

    If none of this is what you really are trying to do then I think more explanation is needed on your goal

  • Sorry for any confusion i may be causing. I am only trying to enter one single URI with subdirectories, or even an exact url.

    when HTTP_REQUEST {
        if { ( [string tolower [HTTP::uri]] starts_with "/helpdesk/webobjects/Helpdesk.woa" ) and not ( [HTTP::cookie exists MRHSession] ) } {
            ACCESS::disable
        } else {
            ACCESS::enable
            return
        } 
    }
    
  • Your latest iRule contains a capital letter in your match string. It'll never match since you are converting to lower case before comparison.