Forum Discussion
Ralph_Duane_761
Nimbostratus
May 13, 2005Rookie needs help. iRule url redirection
I am a newbie with BigIP and not much of a coder either. I want to use BigIP to redirect traffic based on the url. If url contains tsa then goto one webpool and if it contains either tsa_test or tsa_train to goto another webpool. The base url is https. The webpools are http.
Can anyone help?
Thanks.
21 Replies
- unRuleY_95363Historic F5 AccountRegarding the "/", there is nothing in your rule that appears to require it's presence. There's nothing in the BigIP that requires it either. Perhaps this is something that the server is requiring? What happens if you take the rule off the virtual and just use one of the pools directly on the virtual? Do you still have to supply the terminating "/"?
If it is the server that is requiring the terminating "/", we can even modify citizen_elah's rule to rewrite the uri to include it. Simply, add "HTTP::uri $uri_info" as a line after the append and this will rewrite the uri to be what's in the $uri_info variable (which has had the extra "/" appended). - Ralph_Duane_761
Nimbostratus
Citizen_elah,
Here is the error I get from the log file.
Wed May 18 10:53:46 EDT 2005 tmm tmm[7731] 01220002 Rule TSARule : Variable uri_info contents: /tsa/
Wed May 18 10:53:46 EDT 2005 tmm tmm[7731] 01220001 TCL error: Rule TSARule - can't use non-numeric string as operand of "!" while executing "if {not{$uri_info ends_with "/"}} { append uri_info "/" log "Variable uri_info contents w\/ \/ appended:" }"
Wed May 18 10:53:52 EDT 2005 tmm tmm[7731] 01220002 Rule TSARule : Variable uri_info contents: /tsa
Wed May 18 10:53:52 EDT 2005 tmm tmm[7731] 01220001 TCL error: Rule TSARule - can't use non-numeric string as operand of "!" while executing "if {not{$uri_info ends_with "/"}} { append uri_info "/" log "Variable uri_info contents w\/ \/ appended:" }"
Any ideas?
Thanks - JRahm
Admin
I'm no TCL expert....it looks like it is trying to do a numerical operation, most likely because the "/" isn't escaped in the if statement. Try this:rule URI_switch { when HTTP_REQUEST { set uri_info [HTTP::uri] log "Variable uri_info contents: $uri_info" if {not {$uri_info ends_with "\/"} } { append uri_info "/" l log "Variable uri_info contents with \/ appended:" } - JRahm
Admin
scratch that....try this:rule URI_switch { when HTTP_REQUEST { set uri_info [HTTP::uri] log "Variable uri_info contents: $uri_info" if {not {$uri_info ends_with "\/"} } { append uri_info "\/" log "Variable uri_info contents w\/ "\/" appended: $uri_info" } - Ralph_Duane_761
Nimbostratus
Neither of those made any difference. - John_Barrett_10
Nimbostratus
From your error it looks as if the "not" is getting in the way. You may want to try (just for trials sake) removing the not and adding an else.if {$uri_info ends_with "/"} { } else { append uri_info "/" log "Variable uri_info contents w\/ "\/" appended:" }
(escaping what needs to be escaped of course) - I had to dig a little bit to found out why the "not" wasn't working with the ends_with operator. Well, it seems that the expansion of the "str1 ends_with str2" occurs after the evaluation of the "not". So, the not operator is getting the string "$uri_info ends_with /" which is why you are getting the error stating that
can't use non-numeric string as operand of "!"
I'll check with unRuleY why this is the case and see if this is something we can fix in a future release.
Also, just to make note that the "/" character does not need to be escaped so all those backslashes aren't needed.
So, what do you do? Well, the previous post answers it for now. I'd suggest you just put your code in the else section like the followingwhen HTTP_REQUEST { set uri_info [HTTP::uri]; log "Variable uri_info contents: $uri_info"; if { $uri_info ends_with "/" } { log "Variable uri_info already ends with /"; } else { append uri_info "/"; HTTP::uri $uri_info; log "Variable uri_info contents with / appended: $uri_info"; } }
*Note, I've added the "HTTP::uri $uri_info" after the append so that the change will take.
Another option, since you are only looking for the last character in the string, is to use the builtin "string index" TCL command (Click here) along with an string comparison operatorwhen HTTP_REQUEST { set uri_info [HTTP::uri]; log "Variable uri_info contents: $uri_info" if { [string index $uri_info end] eq "/" } { log "Variable uri_info already ends with /"; } else { append uri_info "/" HTTP::uri $uri_info; log "Variable uri_info contents with / appended: $uri_info" } }
Or, if you only care about the else clause, you can use the "ne" string operatorwhen HTTP_REQUEST { set uri_info [HTTP::uri]; log "Variable uri_info contents: $uri_info" if { [string index $uri_info end] ne "/" } { append uri_info "/" HTTP::uri $uri_info; log "Variable uri_info contents with / appended: $uri_info" } }
-Joe - Ralph_Duane_761
Nimbostratus
Everyone,
Thanks for all your replies and help. I think I'm going to step back and punt on this one. When I put in the code to add the / to the end of the url, it works but then it keeps adding a / to the end when you start trying to goto subsequent web pages within the application and this keeps causing problems. I'm sure thare is a way to only add the / when connecting to the base url but I think it will be easier to just have users add the / to the end of the url when going to the web page than having BigIP add it. - unRuleY_95363Historic F5 AccountThe problem here is due to the use of braces instead of parenthesis.
You need to be aware/careful about the when to use braces {} vs. parenthesis () in an expression. This is actually a case where you wanted parenthesis not braces. The use of braces was causing the not operator to work on the string {$uri_info ends_with /} and not the result of the expression ($uri_info ends_with /). I'm sorry if this is confusing, but that is a nuance of Tcl.
So, the correct form of the problematic line would be:if {not ($uri_info ends_with /) } { - drteeth_127330Historic F5 AccountI am still concerned if you need to add the trailing slash when going through BIG-IP, but not if you connect to the webserver directly. Is this the case? If so, what do the webserver logs show? Do the requests look the same?
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)Recent Discussions
Related Content
DevCentral Quicklinks
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com
Discover DevCentral Connects
