cancel
Showing results for 
Search instead for 
Did you mean: 

Issues to forward requests with 'start with' due to similar contexts under same domain

awakenings
Nimbostratus
Nimbostratus

Hi everybody,

A network request that seemed to be simple is giving some trouble to our network team, I'd appreciate some help.
Here's a summary of the rules to be put in place:

1) example.domain.com/cali --> forward to server1

2) example.domain.com --> forward to server2

When creating the rule with "URI starts with" from web interface it works, but there's a side effect: requests like example.domain.com/california are matching rule 1) and therefore failing, since that context is managed by some Apache at server2.

They've tried using 'IS' instead 'STARTS WITH' for /cali but then, when trailing slash is not added, it fails. It also fails when calling something like /cali/ad
Since we don't know what other possible contexts might be requested, we want just to add a rule for /cali and leave everything else (/california , /calisthenics, ...) under rule 2)

What's the issue here? Is something like it possible just using the web interface or are iRules needed? Any examples?



Thanks a lot in advance

1 ACCEPTED SOLUTION

Hi @awakenings ,

you might use the regexp, but using globbing is probably less CPU intensive:

when HTTP_REQUEST {
   # Check the requested path (set to lowercase)
   # -glob: allow string pattern matching
   switch -glob -- [string tolower [HTTP::path]] {
      "/cali" -
      "/cali/" -
      "/cali/*" {
         log local0. "Matched pool 1 paths for [HTTP::uri]"
         pool pool1
      }
      "/california" -
      "/california/" -
      "/california/*"  {
         log local0. "Matched pool 2 paths for [HTTP::uri]"
         pool pool2
      }
      default {
         log local0. "Hit default for [HTTP::uri]"
         pool pool_default
      }
   }
}

This will send traffic to /cali and following segments to pool1 while traffic to /california and following segments will be forwarded to pool2.

 

View solution in original post

4 REPLIES 4

In case you want to consider multiple URLs for content switching I would recommend using a switch statement with globbing und a non-case sensitive lookup of the URI path.

Using the switch statement is described here: https://clouddocs.f5.com/api/irules/switch.html.

Make sure to use OneConnect, to be able to differentiate between requests in the same KeepAlive connection.

 

UPDATE: I just realized I can add just /cali and that should be it

when HTTP_REQUEST {

   # Check the requested path (set to lowercase)
   # -glob: allow string pattern matching
   switch -glob -- [string tolower [HTTP::path]] {
      "/cali" -
"/cali/*" { log local0. "Matched pool 1 paths for [HTTP::uri]" pool pool1 } default { log local0. "Hit default for [HTTP::uri]" pool pool_default } } }


Thanks a lot! 🙂

Hi @awakenings ,

you might use the regexp, but using globbing is probably less CPU intensive:

when HTTP_REQUEST {
   # Check the requested path (set to lowercase)
   # -glob: allow string pattern matching
   switch -glob -- [string tolower [HTTP::path]] {
      "/cali" -
      "/cali/" -
      "/cali/*" {
         log local0. "Matched pool 1 paths for [HTTP::uri]"
         pool pool1
      }
      "/california" -
      "/california/" -
      "/california/*"  {
         log local0. "Matched pool 2 paths for [HTTP::uri]"
         pool pool2
      }
      default {
         log local0. "Hit default for [HTTP::uri]"
         pool pool_default
      }
   }
}

This will send traffic to /cali and following segments to pool1 while traffic to /california and following segments will be forwarded to pool2.

 

And if you prefer using regexp for even better granularity you can try this:

when HTTP_REQUEST {
    switch -regexp -- [HTTP::path] {
        "(?i)^/cAli(|/|/.*)$" {
            # log local0. "[HTTP::path] matches /cali and sub segments"
            set response_string "[HTTP::path] matches /cali and sub segments\r\n"
        }
        "(?i)^/califOrnia(|/|/.*)$" {
            # log local0. "[HTTP::path] matches /california and sub segments"
            set response_string "[HTTP::path] matches /california and sub segments\r\n"
        }
        default {
            # log local0. "[HTTP::path] not matches regexp"
            set response_string "[HTTP::path] not matches regexp\r\n"
        }
    }
    HTTP::respond 200 content "${response_string}" noserver Connection Close
    unset response_string
    return
}

 

 

It is:

  • case insensitive: '(?i)'
  • matching the whole path: '^' to '$'
  • looking for specific segment and sub-segments: '(|/|/.*)'
  • responding directly for testing purposes by using HTTP::respond

It is important to notice the difference of applying the functions of HTTP::path, HTTP::uri, HTTP::query.