Forum Discussion

adminas's avatar
adminas
Icon for Altocumulus rankAltocumulus
Jul 10, 2024

Need help with iRule based on host and path

Hello all.

I am trying to create an iRule that will choose a specific pool based on host and path. I tried the following code:

when HTTP_REQUEST {
  if { [HTTP::host] equals "hostname_a"} {
    if { [HTTP::path] equals "/path" } {

      pool pool_a
        log local0. "URL : [HTTP::host][HTTP::uri] entered"
    }
  }
  if { [HTTP::host] equals "hostname_b"} {
    if { [HTTP::path] equals "/path" } {

        pool pool_b
        log local0. "URL : [HTTP::host][HTTP::uri] entered"
    }
  } 
}

According to Big-IP stats, the iRule gets executed but it doesnot direct the call to the pool (pool stats shows 0) specified although logging is invoked and I get the URL in the ltm logs.

Right after this script there is another one which gets executed and works as it should be. It specifies even more conditions for a series of pools and if none is matched then directs the call to the default pool specified there.

The problem is with the first one. I would like it to be executed and unless there is a match, then it should proceed to executing the second one. 

If you can give me some advice it would be highly appreciated. Thank you.

  • Finally, problem solved! The reason was the order of execution for the 2 scripts. I donot really understand why this happens but when I placed the script in second place, everything is executed as expected. If you have any ideas please let me know.

    The problematic order which doesnot work is shown below:

    First script:

    when HTTP_REQUEST {
      if { [HTTP::host] equals "hostname_a"} {
        if { [HTTP::path] equals "/path" } {

          pool pool_a
            log local0. "URL : [HTTP::host][HTTP::uri] entered"
        }
      }
      if { [HTTP::host] equals "hostname_b"} {
        if { [HTTP::path] equals "/path" } {

            pool pool_b
            log local0. "URL : [HTTP::host][HTTP::uri] entered"
        }
      } 
    }

     

    Second script:

    when HTTP_REQUEST {
    if {[HTTP::has_responded]}{return}
        switch -glob [string tolower [HTTP::path]]
        {

    ....

    ....

        }

        default
        {
                switch [string tolower [HTTP::host]]
                {

                     "hostname_a"

                     {

                       pool pool_c
                       persist none

                      }

    ....

    .....

                      default

                       {

                             pool_z

                       }

    ......

    Anyway, thank you all very much for your time.

  • Finally, problem solved! The reason was the order of execution for the 2 scripts. I donot really understand why this happens but when I placed the script in second place, everything is executed as expected. If you have any ideas please let me know.

    The problematic order which doesnot work is shown below:

    First script:

    when HTTP_REQUEST {
      if { [HTTP::host] equals "hostname_a"} {
        if { [HTTP::path] equals "/path" } {

          pool pool_a
            log local0. "URL : [HTTP::host][HTTP::uri] entered"
        }
      }
      if { [HTTP::host] equals "hostname_b"} {
        if { [HTTP::path] equals "/path" } {

            pool pool_b
            log local0. "URL : [HTTP::host][HTTP::uri] entered"
        }
      } 
    }

     

    Second script:

    when HTTP_REQUEST {
    if {[HTTP::has_responded]}{return}
        switch -glob [string tolower [HTTP::path]]
        {

    ....

    ....

        }

        default
        {
                switch [string tolower [HTTP::host]]
                {

                     "hostname_a"

                     {

                       pool pool_c
                       persist none

                      }

    ....

    .....

                      default

                       {

                             pool_z

                       }

    ......

    Anyway, thank you all very much for your time.

  • Hi. I am fine and hope the same for you!

    Thank you very much for your reply but the are already 3 working iRules that I cannot remove / convert and I need just an extra iRule to be executed in the beggining and move to the next script if no match is found. Its a production system and I cannot really experiment as I have no experience in policies.

    • JoseLabra's avatar
      JoseLabra
      Icon for MVP rankMVP

      And if you captured the traffic with tcpdump and test the iRule, you see the LB correctly?
      I remember a scenario with the same issue, the pool dont show the stats, but the LB its working.

       

      if was the case, open a ticket to support for more detail

      • adminas's avatar
        adminas
        Icon for Altocumulus rankAltocumulus

        Thank you.. I tried with tcpdump -nnvvi but cannot see any request going to the pool specified. I can see only health checking.

      • adminas's avatar
        adminas
        Icon for Altocumulus rankAltocumulus

        Thank you for your suggestion but there is no change. 

  • Can u try with below example, u can add specific uri and host name. u can edit it based on your different host and path

     

    when HTTP_REQUEST {
        # Define pool selection based on host and path
        if { [HTTP::host] eq "example.com" } {
            if { [HTTP::uri] starts_with "/app1" } {
                pool pool_app1
            } elseif { [HTTP::uri] starts_with "/app2" } {
                pool pool_app2
            } else {
                pool default_pool
            }
        } elseif { [HTTP::host] eq "anotherexample.com" } {
            if { [HTTP::uri] starts_with "/service1" } {
                pool pool_service1
            } elseif { [HTTP::uri] starts_with "/service2" } {
                pool pool_service2
            } else {
                pool default_pool
            }
        } else {
            # Fallback to a default pool if no match is found
            pool default_pool
        }
    }