Forum Discussion

kevin_50596's avatar
kevin_50596
Icon for Nimbostratus rankNimbostratus
Jul 10, 2008

Multi-part Irule

Hello, I'm fairly new to writing iRules so I'm not sure exactly how to get this done. Any help would be greatly appreciated.

 

 

Here's some data to give you context for what I'm trying to do:

 

 

1. Any http request coming into this Virtual Server with a uri ending in "/forms" needs to be redirected to a second pool seperate from the default pool. All other http requests should go to the default pool.

 

 

2. If the second pool doesn't have any active nodes, a third pool must be selected and the http request must be redirected there.

 

 

There are two iRules I've found which I think will accomplish this, but I'm not sure how to combine them into a single iRule.

 

 

Here they are:

 

 

when HTTP_REQUEST {

 

if {[HTTP::host] contains "/forms"} {

 

pool SECOND_POOL

 

}

 

}

 

 

and

 

 

when CLIENT_ACCEPTED {

 

if {[active_members SECOND_POOL] < 1}{

 

pool THIRD_POOL

 

}

 

}

 

 

Thanks again for any help,

 

Kevin

5 Replies

  • Hi Kevin,

    I think this will work for you. If you run into any issues, check /var/log/ltm for debug output. You can add more debug statements to see what's happening. Once you're done testing, you can comment out the log statements to save resources.

     
     when HTTP_REQUEST { 
      
        log local0. "[IP::client_addr]:[TCP::client_port]: New request to [HTTP::uri]" 
      
         Check if URI contains /forms 
        if {[HTTP::uri] contains "/forms"} { 
      
           log local0. "[IP::client_addr]:[TCP::client_port]: active members: [active_members SECOND_POOL]" 
      
            Use the second pool if it has available members 
           if {[active_members SECOND_POOL] > 0}{ 
              pool SECOND_POOL 
      
           } else { 
               Second pool was down, so use the third pool 
              pool THIRD_POOL 
           } 
        } 
     } 
     

    Aaron
  • Thanks for your help, man! I'll test everything out and reply with the outcome.

     

     

    Kevin
  • Well, that worked wonderfully! Thanks again for your help. Unfortunately, and as always, the plot thickens.

     

     

    The guy I had originally discussed this change with didn't give me all the facts. Here be the situation:

     

     

    Any http request coming into "http://www.site1.org/forms" must be somehow be redirected to "http://www.site2.com/forms".

     

     

    The problem is that "/forms/" has subdirectories. Therefore I don't think a simple redirect will do the trick. Also, since it's the URL which needs changed and not just the uri, a uri rewrite won't work either. I tried it but was unsuccessful. Is there a way to do some kind of partial URL rewrite while still leaving "/forms/..." and trailing subdirectories intact?

     

     

    For example, the iRule you put together for me would take a request for "www.site1.org/forms/sub1/sub2" and redirect it to "www.site2.org/forms" without keeping "/sub1/sub2".

     

     

    Is this even possible?
  • Can you list out the logic for what should be redirected to a new URL, what should be sent to a pool and what if anything you want rewritten as before the request is sent to the pool? If you can include the Host and/or URI checks you want to use, we can provide some more examples.

     

     

    In general, you can get the host value using HTTP::host, you can get the URI using HTTP::uri, you can issue a redirect using HTTP::redirect, and you can specify a pool using the pool command.

     

     

    The wiki pages have more detail on the commands (Click here).

     

     

    Aaron
  • Colin_Walker_12's avatar
    Colin_Walker_12
    Historic F5 Account
    Here's some slightly updated code:

     

     

     

     
     when HTTP_REQUEST {  
       log local0. "[IP::client_addr]:[TCP::client_port]: New request to [HTTP::uri]"  
        Check if URI contains /forms  
       if {[HTTP::uri] starts_with "/forms"} {  
         if { [HTTP::host ne "site2.com" } { 
           HTTP::redirect "http://site2.com[HTTP::uri]" 
         } else { 
           log local0. "[IP::client_addr]:[TCP::client_port]: active members: [active_members SECOND_POOL]"  
            Use the second pool if it has available members  
           if {[active_members SECOND_POOL] > 0}{  
             pool SECOND_POOL  
           } else {  
             Second pool was down, so use the third pool  
            pool THIRD_POOL  
           }  
         }  
       } 
     } 
     

     

     

    Basically this is the same iRule, except that it performs a host check, too. Basically, you set both domains to point to the VIP address. Then, when traffic comes in from site1.org with /forms at the start of the URI, it will do an HTTP redirect to site2.com while maintaining the exact same URI (we already know it contains forms, so we don't need to rebuild it or strip forms out or anything, we just keep the whole thing intact as is). It will then hit the same VIP, again, and process through the second half of the iRule, as it won't get caught by the Host check this time. Now it'll hit the pool logic portion that elah built for you, and everyone should be happy.

     

     

    Make sense?

     

     

    Colin