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

Filter by:
  • Solution
  • Technology
Answers

nesting switch within aif statement

I'm trying to nest a switch statement in a if statement but am getting a parse error


[parse error: PARSE syntax 302 syntax\ error\ in\ expression\ \"\ switch\ -glob\ \[string\ tolower\ \[HTTP::uri\]\]\ \{\n\t\t\""/fr/app*"\"\ -\n...\":\ variable\ references\ require\ preceding\ \$] [{ switch -glob [string tolower [HTTP::uri]] {

can anybody see my error or suggest a alternative method

when HTTP_REQUEST { if { [URI::path [HTTP::path]] starts_with "/xyz/" || [HTTP::query] contains "xy=9" } { if { [HTTP::method] equals "GET" && [HTTP::header exists "Upgrade"] && [HTTP::header Upgrade] contains "WebSocket" } { HTTP::disable } pool pool3 } elseif { switch -glob [string tolower [HTTP::uri]] { "/fr/app*" { pool pool2 } default { pool Pool1 } } } else { pool pool1 } }

0
Rate this Question

Answers to this Question

placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
Would you mind listing everything this rule should be doing? I'm having a bit of trouble deciphering it. :-P

0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
we have an application which uses websockets through various means we run these over port 80 due to firewall concerns
the first If part of the irule picks out this websocket traffic we found we needed to use http::disable to allow some of the methods this application employs to work through the F5
all this traffic should be going to pool3
we then have some more pools which the rest of the traffic should be directed to depending on the country version of the website they are trying to goto as determined by the uri containg the country code (thats the pool 2 bit i stripped out a load of other options and pools).
then all other traffic not going to the country specific version of the site should goto the default pool1.
the last else statement is just a fall back from before the I tried to implement the Switch and instead had a series of if else statements
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
sorry to clear up the nested if statement to start with
not all the traffic that goes to this application that uses websockets requires HTTP::disable thus the nested if

have added a few comments below

[codewhen HTTP_REQUEST {
#check is for websocket server (if it is then check if it is websocket if so disable HTTP then pass to pool3 else leave alone and pass to pool3)
if { [URI::path [HTTP::path]] starts_with "/xyz/" || [HTTP::query] contains "xy=9" } {
#check is web socket
if { [HTTP::method] equals "GET" && [HTTP::header exists "Upgrade"] && [HTTP::header Upgrade] contains "WebSocket" } {
#disbale http for websocket traffic
HTTP::disable
}
#send to pool3
pool pool3
#check which country it is for and send to coresponding server
} elseif { switch -glob [string tolower [HTTP::uri]] {
"/fr/app*" { pool pool2 }
default { pool Pool1 }
}
} else {
#if it doesnt meet any of that criteria send to pool1
pool pool1
}
}
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
Here's what I came up with.
1. I got rid of the "URI::path" and justed used "HTTP::path." Any reason you were using both?
2. I'm assuming your "| |" meant "or." I'm admittedly a bit rusty on that front. :-P.
3. I referenced "pool3" twice in the "WebSocket" part as I wanted to cover both "if" statements. That might not have been necessary but I would have expected the second if to use the default pool if one wasn't selected.
4. Rather than both checking to see whether the header existed and checking to see what it contained, I simply checked whether the header contained the "WebSocket" value. If the header didn't exist, it obviously wouldn't contain said value so I assumed I could do away with that check.
5. You can't really "if" a switch statement which is why you were running into problems.

Give this a shot and let me know what you see.



when HTTP_REQUEST {
   if { [string tolower [HTTP::path]] starts_with "/xyz/" or [string tolower [HTTP::query]] contains "xy=9" } {
        if { [HTTP::method] eq "GET" and [HTTP::header "Upgrade"] contains "WebSocket" } {
             HTTP::disable 
             pool pool3 }
        pool pool3 
   } else { 
            switch -glob [string tolower [HTTP::uri]] {
                           "/fr/app*" { pool pool2 }
                            default { pool pool1 }
              }
          }
    }
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
Cheers now writen like that I see my obvious error Doh!

I cant use Switch within an IFELSE statement because its not and IF condition!

Thanks for your help!
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
Posted By TMaCEvans on 01/17/2011 09:02 AM
Cheers now writen like that I see my obvious error Doh!

I cant use Switch within an IFELSE statement because its not and IF condition!

Thanks for your help!

My pleasure...does the logic work properly?
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
Hi,

Does the above logic worked for WebSocket? I am also trying for something similar and i am getting as response pending from chrome browser.

The scenario i am trying is:

1. Chrome browser has the url to the application as ws and the request is sent to vip
2. vip is configured with https
3. vip has an irule that, if http header's Upgrade contains WebSocket, disable http and send the request to a different pool
4. the back end server pool supports websocket and will respond back.

Without load balancer in between the client and the server, i can get the requests / responses. However if i apply the above rule, i see the Response as pending from browser and the calls are made to the server and immediately the socket getting closed.


Could you please help.

Thanks.




0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
if { [HTTP::method] equals "GET" && [HTTP::header exists "Upgrade"] && [HTTP::header Upgrade] contains "WebSocket" }
{ HTTP::disable } pool websocketserver

I use this in my I-rule
I'm using wss instead of ws as i had a few problems with ws
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
Hi,

Thanks for the reply. I still get the error.

i tried with both url as ws://domain.com:443/.... & wss://domain.com:443/...

with load balancer rule as

when HTTP_REQUEST {
if { [HTTP::header Upgrade] contains "WebSocket" }
{
HTTP::disable
pool ws-pool
}
}

Anything i am missing?
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
Sorry posted twice. Removing the duplicate.
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

We ran into this same issue, and we were able to get past it by adding a 'tolower' conversion as follows:

 

when HTTP_REQUEST {
 
   if { [string tolower [HTTP::header Upgrade]] contains "websocket" }
   {
      HTTP::disable
      pool pool_pool1_ws
   }
   else
   {
      pool pool_pool1_http
   }
}
0