Forum Discussion

Tony2020's avatar
Tony2020
Icon for Nimbostratus rankNimbostratus
Aug 30, 2018

Redirect to pool based on URI not working

Hi All,

I am having issues with a redirect within an Irule.

Here is what I am trying to do.

  1. If users coming from the internet (not matching datagroup 10.0.0.0/8) and they go to "/test" they should continue to get forwarded to the servers in the "TESTPOOL" without issues. However if they go to the main site or any other URI not matching this, they should get redirected to the maintenance page. ** This is not working -- they get redirected to maintenance page regardless if they put in the /test URI or not ***

    1. If users coming from the internal network matching the data group (10.0.0.0/8), they should be sent to the servers in the pool regardless the URI or what they are trying to access...This is working...

Can anyone let me know what I am missing where external users going to "/test" URI should get processed?

Thanks for the help!

    when HTTP_REQUEST {
     switch -glob [string tolower [HTTP::uri]] {
           "/test" {
              pool TESTPOOL_443
               } 
          }

            if {([class match [IP::client_addr] equals DG-INTERNAL-IP])} {
                 pool TESTPOOL_443

          } else {
                 HTTP::redirect "http://maintenance.test.com"  
        }
  }

8 Replies

  • Hi

    I think you need to re-order your logic slightly so that the redirect only happens if all other logic doesn't fire. Try something like this

        when HTTP_REQUEST {
                if {([class match [IP::client_addr] equals DG-INTERNAL-IP])} {
                     pool TESTPOOL_443
    
              } elseif {
                [string tolower [HTTP::uri]] eq "/test"} {
                    pool TESTPOOL_443
                } else {
                     HTTP::redirect "http://maintenance.test.com"  
            }
      }
    
  • Try this,

    and if you use several pool on your vs you can set a profil oneconnect:

    when HTTP_REQUEST {
    
    if { [class match [IP::client_addr] equals DG-INTERNAL-IP] || [string tolower [HTTP::uri]] starts_with "/test"} {
        pool TESTPOOL_443
    } else {
        HTTP::redirect "http://maintenance.test.com"  
    }
    
    }
    
  • thanks for the help. Also tried this version of your irule. Is there a way in your irule to send all traffic to the maintenance page if access externally (not matching the data group)? They only time external users should get sent to the server in the pool is if they put in the URI "/test"...otherwise no matter if they go the the main page or go to any other URI then /test, they get the maintenance page.

     

  • So the answer to your issue is that you can set the pool multiple times in the iRule - it will follow the logic to the end of the iRule and only at that point will it send to the allocated pool. In your case you set the pool based on the URI, then you re-set it based on the IP and then the iRule ends.

    Soooo.... you should work out your pseudocode so that it logically does what you want and build your iRule appropriately eg

    if IP == internal then set pool X
    elseif URI == /test then set pool Y
    else do something else
    

    The other thing that you can do is to use the

    return
    command to exit the iRule once you set the pool the first time:

    when HTTP_REQUEST {
      switch -glob [string tolower [HTTP::uri]] {
        "/test" {
          pool TESTPOOL_443
          return
          } 
      }
    <...>
    
  • you can use following code

     

    when CLIENT_ACCEPTED {
      set internal_network [class match [IP::client_addr] equals DG-INTERNAL-IP]
      set insert_cookie 0
    }
    
     when HTTP_REQUEST {
      if {$internal_network} {
        pool TESTPOOL_443
      } elseif {[URI::query [HTTP::uri] bypassMaintenance] equals "true"} {
          HTTP::respond 302 Location [HTTP::path] "Set-Cookie" "bypassMaintenance=true;path=/"
      } elseif {[URI::query [HTTP::uri] bypassMaintenance] equals "false"} {
            HTTP::respond 302 Location [HTTP::path] "Set-Cookie" "bypassMaintenance=false;expires=Thu, 01-Jan-1970 00:00:01 GMT;path=/"
      } elseif {[HTTP::cookie value bypassMaintenance] equals "true"} {
        pool TESTPOOL_443
      } else {
        HTTP::redirect "http://maintenance.test.com"  
      }
    }

    the bypass uri is :

     

    /?bypassMaintenance=true
    
    or 
    
    /WhateverYouWant?bypassMaintenance=true
  • You can try something like that

        when HTTP_REQUEST {
        switch -glob [string tolower [HTTP::uri]] {
            "/test" {
                pool TESTPOOL_443
            }
            default {
                if {([class match [IP::client_addr] equals DG-INTERNAL-IP])} {
                        pool TESTPOOL_443
                } else {
                        HTTP::redirect "http://maintenance.test.com"  
                }
            }
        }
    }
    
  • For some reason, if I am externally (not in data group matching 10.0.0.0/8) and i go to /test URI, it still sends me to the maintenance page..are we missing something here? Seems that it is not looking at the switch command..

     

    thank you.

     

  • Oh.. I forgot to write "return" in (each) switch case.

        when HTTP_REQUEST {
    switch -glob [string tolower [HTTP::uri]] {
        "/test" {
            pool TESTPOOL_443
            return
        }
        default {
            if {([class match [IP::client_addr] equals DG-INTERNAL-IP])} {
                    pool TESTPOOL_443
            } else {
                    HTTP::redirect "http://maintenance.test.com"  
            }
        }
    }
    

    }