Forum Discussion

keefyweefy's avatar
keefyweefy
Icon for Nimbostratus rankNimbostratus
Jul 08, 2011

irule to redirect and amend URI

Hi

 

 

 

I'm trying to write a redirect irule but not having much joy.

 

 

 

The irule firstly needs to identify wireless clients then direct them to poolA

 

Then it needs to identify internal clients and direct them to poolB, but whilst redirecting to poolB also needs to check if the uri starts with / and ammend to /newuri

 

All external clients should go to poolA

 

 

 

The default resource on the VS is poolA.

 

We have a data group called Wireless with all relavant subnets identified.

 

 

 

What I have so far is:

 

 

 

when HTTP_REQUEST {

 

if { [matchclass [IP::remote_addr] equals $::Wireless] } {

 

pool PoolA

 

} elseif { [IP::addr [IP::client_addr]/16 equals 192.168.0.0] } {

 

pool poolB

 

}

 

}

 

 

 

This works well, I also have the following irule:

 

 

 

when HTTP_REQUEST {

 

if {[HTTP::uri] == "/"}{

 

HTTP::redirect "/newuri"

 

}

 

}

 

 

 

Which will happly replace the uri, what I need is the two combined but URI rewriting only for internal clients only.

 

  • I'm assuming you've tried just merging the two and it didn't work...but I'm not sure why it wouldn't. Have you done something like this?

     

    when HTTP_REQUEST {

    if { [matchclass [IP::remote_addr] equals $::Wireless] } {

    pool PoolA

    } elseif { [IP::addr [IP::client_addr]/16 equals 192.168.0.0] } {

    if {[HTTP::uri] == "/"}{

    HTTP::redirect "/newuri"

    return

    }

    pool poolB

    }

    }

  • Another option... does the rule have to do a redirect? Would it be okay if it just modified the URI on the way to the pool but didn't update the client's location?

    ...

    elseif { [IP::addr [IP::client_addr]/16 equals 192.168.0.0] } {

    if {[HTTP::uri] == "/"}{

    HTTP::uri "/newuri"

    }

    pool poolB

    }

    ...

  • Colin_Walker_12's avatar
    Colin_Walker_12
    Historic F5 Account
    What version are you running? I'm assuming version 9.x since you're still using matchclass. If that's the cast, and it were me, I'd write it something like this:

    
    when CLIENT_ACCEPTED {
      if { ([matchclass [IP::client_addr] equals $::Wireless]) || !([IP::addr [IP::client_addr] equals 192.168.0.0/16]) } {
        set pool "poolA"
      } else {
        set pool "poolB"
      }
    }
    
    when HTTP_REQUEST {
      if { ($pool eq "poolB") && ([HTTP::uri] eq "/")} {
         HTTP::redirect "/newuri"
      } else {
        pool $pool
      }
    }
    

    By doing all of the IP lookups in the CLIENT_ACCEPTED event you're saving a fair amount of cycles for every HTTP request past the first one, which is generally a lot since there are 35-50 requests required to load the average web page. Take into account browsing multiple pages per connection and you'll save a heap of resources by getting as much logic into CLIENT_ACCEPTED as you can. I also tightened up a couple of the logical statements, but that's just how they make sense to me, there are lots of options on how to write them.

    That being said, that's assuming you want to use HTTP::redirect for some reason. If you can get away with the HTTP::uri command like Peter mentioned, that's one less set of requests that need to be made and should be faster for your clients, just keep in mind that it behaves very differently.

    Colin
  • You could take 192.168.0.0/16 out of the Wireless datagroup and then remove the IP::addr check. Also, if you're on 9.4.4 or higher you can remove the $:: prefix from the datagroup name in the iRule to preserve CMP:

     

     

    http://devcentral.f5.com/wiki/default.aspx/iRules/CMPCompatibility.html

     

     

    Aaron