Learn F5 Technologies, Get Answers & Share Community Solutions Join DevCentral

Filter by:
  • Solution
  • Technology
Answers

Need help with Irule to redirect based on http path or host header

I need to create an irule that will redirect traffic to a different pool bassed on the following criteria. The http path begins with /socket.io OR ((The http header 'Upgrade' contains the string 'WebSocket') AND (the http header 'Host' begins with 'ws')). This is what I have so far, any help is appreciated.

# Assign a pool HTTP path

when HTTP_REQUEST {
    switch -glob [string tolower [HTTP::path]] { 
        "/socket.io*" {
        # select the pool 
            pool poolA

    }

elseif HTTP::request {
    switch -glob [string tolower [http_host]] contains { "
0
Rate this Question

Answers to this Question

placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

Try this, just a quick iRule thrown together

when HTTP_REQUEST {
    if { [string tolower [HTTP::path]] starts_with "/socket.io" } {
       pool poolA
       } elseif { { [HTTP::header "Upgrade"] contains "Upgrade" } && { [string tolower [HTTP::host]] starts_with "ws" } } {
       pool poolb
       }
}
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

Just be careful, the first condition for your elseif will be :

elseif { { [HTTP::header "Upgrade"] contains "WebSocket" } && { [string tolower [HTTP::host]] starts_with "ws" } } {

The mistake was just on "Upgrade" instead of "WebSocket"

0
Comments on this Answer
Comment made 20-Nov-2013 by Richard Harlan
Good catch typed to fast. Thanks
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

So next question if none of those conditions match will the default pool be chosen or do I have to put else default at the end of the rule?

0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

Yes you're right, if none of this conditions match your default pool will be chosen.

0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

Here is the irule I have, let me know if it looks correct.

#Assign a pool HTTP path matches
 when HTTP_REQUEST {
 if {
 { [string tolower [HTTP::path]] starts_with "/socket.io" } {
    pool pl_vantage-beta_1337
#Or if header string matches    
} elseif { { [HTTP::header "Upgrade"] contains "WebSocket" } && { [string tolower  [HTTP::host]] starts_with "ws" }} {
    pool pl_vantage-beta_1337 }
#Otherwise use default pool
    default {
        pool pl_vantage-beta_http
    }
} 
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

Your last condition is not good. Default is only used when you use the "switch" parser instead of multiples if, elseif...

So you can replace default by else and it will work.

Remember that you don't need to use your last line with the else, because on your virtual server you can set a default pool.

0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

Awesome, thanks for the help guys I am going to test this out today.

0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

Here is the final irlule, when I add it to the virtual everything breaks. If you guys could take a look I would appreciate it. Thanks

 #Assign a pool HTTP path matches
 when HTTP_REQUEST {
 if { [string tolower [HTTP::path]] starts_with "/socket.io" } {
    pool pl_vantage-beta_1337
#Or if header string matches    
} elseif { { [HTTP::header "Upgrade"] contains "WebSocket" } && { [string tolower  [HTTP::host]] starts_with "ws" }} {
    pool pl_vantage-beta_1337 }
#Otherwise use default pool
    }
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

Everything breaks ?!
Could you tell us what you're're doing as tests ?

0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

Just going to the page via internet explorer. When I go to the main page with no uri I get nothing back. So none of the conditions should match and I should be sent to the default pool. Works fine before I put the irule in.

0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

Is it a SSL traffic ? If yes are you doing SSL termination on your BIG-IP ?
Otherwise, could you add a pool assign condition to your last line in order to check if it matches your iRule.

0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

It is SSL traffic and it is being terminated on the LTM. I'm not following you on the pool assign condition.

0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

Sorry, I made a mistake using the word condition.

What I suggested to you is to add this at the end of your iRule

#Otherwise use default pool
pool your_poolname
}
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

do I need an else before that statement?

0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

You can add an else but it's not mandatory because it's your last order in your iRule.

0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

New irule still doesn't work, same as before. Going to try support. Thanks

#Assign a pool HTTP path matches
 when HTTP_REQUEST {
 if { [string tolower [HTTP::path]] starts_with "/socket.io*" } {
    pool pl_vantage-beta_1337
#Or if header string matches    
} elseif { { [HTTP::header "Upgrade"] contains "WebSocket" } && { [string tolower  [HTTP::host]] starts_with "ws" }} {
    pool pl_vantage-beta_1337 }
#Otherwise use default pool
    pool pl_vantage-beta_http
    }
0