Forum Discussion
TCL errors
we have following irule configured and it's throwing large amount of TCL errors evenif logging is disable for the irule. It's working ok and in production but not sure why it cause TCL errors
when HTTP_REQUEST {
Redirect request to the matching data_group value
set redirect_url [class match -value [string tolower [HTTP::uri]] equals VURL_[string tolower [HTTP::host]]]
log local0. "Redirecting: [HTTP::host][string tolower [HTTP::uri]] to $redirect_url "
HTTP::redirect $redirect_url
}
}
TCL errors
Aug 11 06:30:09 slot1/PRD err tmm[19587]: 01220001:3: TCL error: /Common/VanityIRule - Could not find class VURL_google (line 1) invoked from within "class match -value [string tolower [HTTP::uri]] equals VURL_[string tolower [HTTP::host]]"
Aug 11 06:30:09 slot1/PRD err tmm[19587]: 01220001:3: TCL error: /Common/VanityIRule - Could not find class VURL_google (line 3) invoked from within "class match -value [string tolower [HTTP::uri]] equals VURL_[string tolower [HTTP::host]]"
Thanks
15 Replies
- Vijay_E
Cirrus
Do you have VURL_google data group ?
- VernonWells
Employee
Runtime platform (either Tcl or invalid iRule command) errors are always logged. You can't really control that (well, outside of suppressing the log level or facility, or placing a catch block around the code). Those errors also terminate the iRule and delete the connection entry. That's part of the reason why logging these types of errors is important.
- Anush
Nimbostratus
Thanks for your comment. Understood. Do you see anything wrong in irule configuration?
- Anush
Nimbostratus
Thanks for your comment. Understood. Do you see anything wrong in irule configuration?
- VernonWells
Employee
The syntax for a class match -value is:
class match -value
This means "retrieve the value associated with the key in the data group named ". In your case, the Host header is "google", so in your code, once HTTP::host expands, you are trying to do this:
class match -value [HTTP::uri] equals VURL_google
but there is no data group named "VURL_google". I suspect you're confusing the use of equals here, which is actually a parameter of class, rather than the normal equals operator. I believe you are trying to lookup the value in a data group that is associated with the key HTTP::uri, then see if that value matches the literal "VURL_google". If I'm right, then let's assume your URI->host matching data group is called dg-uri-host. Your code would be:
when HTTP_REQUEST { set redirect_url [class lookup [string tolower [HTTP::uri]] dg-uri-host] HTTP::redirect $redirect_url }If you were trying to make this conditional, then it would be:
when HTTP_REQUEST { set redirect_url [class lookup [string tolower [HTTP::uri]] dg-uri-host] if { $redirect_url eq "VURL_google" } { HTTP::redirect $redirect_url } }Note that this:
class lookup
is synonymous with this:
class match -value equals
Also note that HTTP::uri is the entire query-uri, which means that, if a client submitted this:
GET /foo/bar/baz.html?this=that&here=there
then HTTP::uri would be "/foo/bar/baz.html?this=that&here=there". You might find the use of HTTP::path more fruitful. Also, while your filesystem may or may not be case-sensitive, the Request-URI path is in fact case-sensitive, so normalizing the case (that is, using string tolower) on the Request-URI or Request-URI path is -- strictly speaking -- not needed and in fact causes differing paths to appear to be equal.
- Anush
Nimbostratus
Thanks Vernon for your details analysis on this. I think, posted TCL errors only for Google.com made confusion here. I have hundreds of TCL errors for different sites in logs, all are due to not find match class. so what I am looking for here is, how to prevent these errors? all your recommendations are excellent and very useful but I think evenif I use those, I may end up with similar TCL errors if request don't find match class or may be I don't understand correctly.
Thanks again for your time.
- Mohamed_Lrhazi
Altocumulus
another option would be to catch the error:
if { [catch { set redirect_url [class match -value [string tolower [HTTP::uri]] equals VURL_[string tolower [HTTP::host]]] }]} { set redirect_url "some default url" }
- Stanislas_Piro2
Cumulonimbus
Hi,
you can check if the data group exists before searching in it:
when HTTP_REQUEST { Redirect request to the matching data_group value if {[class exists VURL_[string tolower [HTTP::host]]]} { set redirect_url [class match -value [string tolower [HTTP::uri]] equals VURL_[string tolower [HTTP::host]]] log local0. "Redirecting: [HTTP::host][string tolower [HTTP::uri]] to $redirect_url " HTTP::redirect $redirect_url } } } - Anush
Nimbostratus
Thanks Vernon for your details analysis on this. I think, posted TCL errors only for Google.com made confusion here. I have hundreds of TCL errors for different sites in logs, all are due to not find match class. so what I am looking for here is, how to prevent these errors? all your recommendations are excellent and very useful but I think evenif I use those, I may end up with similar TCL errors if request don't find match class or may be I don't understand correctly.
Thanks again for your time.
- VernonWells
Employee
Ah, so you are performing that match on purpose. Got it. You can either use the catch method already articulated, or:
set cn "VURL_[string tolower [HTTP::host]]" if { [class exists "$cn"] } { set redirect_url [class lookup [HTTP::path] $cn] ... etc ... }The problem with using catch is, it will catch any runtime error, not just this one, so you could end up masking a different issue, which you would actually want to log.
Incidentally, the quoting I use above (in the set ... command and the class exists ... command) is intentional. If a space creeps in anywhere, it'll cause a runtime exception. Since class names cannot have spaces, and you validated the existence in the class exists ..., quoting isn't needed in the class lookup ....
Also, ordinarily we recommend against variable assignment for command retrieved values (e.g., it's not usually necessary to assign [HTTP::path] to a variable, even if it's referenced more than once because it is generally cheaper to get the value from the command each time than to expand a Tcl variable). In this case, however, we want to avoid duplicate execution of string tolower ...; hence the assignment.
- Anush
Nimbostratus
Much appreciated Vernon. I will try following
set cn "VURL_[string tolower [HTTP::host]]" if { [class exists "$cn"] } { set redirect_url [class lookup [HTTP::path] $cn] HTTP::redirect $redirect_url log local0. "Redirecting: [HTTP::host][string tolower [HTTP::uri]] to $redirect_url " } - Anush
Nimbostratus
question on HTTP::path - is it case sensitive too?
what if someone type abc.com/F5Devcentral
and configured class has only lowercase item means /f5devcentral
is it going to be hit or miss in class?
Thanks
- Anush
Nimbostratus
Much appreciated Vernon. I will try following
set cn "VURL_[string tolower [HTTP::host]]" if { [class exists "$cn"] } { set redirect_url [class lookup [HTTP::path] $cn] HTTP::redirect $redirect_url log local0. "Redirecting: [HTTP::host][string tolower [HTTP::uri]] to $redirect_url " } - Anush
Nimbostratus
question on HTTP::path - is it case sensitive too?
what if someone type abc.com/F5Devcentral
and configured class has only lowercase item means /f5devcentral
is it going to be hit or miss in class?
Thanks
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)Recent Discussions
Related Content
* 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
