Forum Discussion
Optimizing redirects to avoid TCL error "Multiple redirect/respond invocations"
Hi everyone,
I would like to ask for help in finding the reason why following rule (stripped out of confidential data) is causing the error of:
Fri Nov 23 04:06:03 GMT 2012 err local/tmm3 tmm3[6833] 01220001 TCL error: goRedirects - Operation not supported. Multiple redirect/respond invocations not allowed (line 21) invoked from within "HTTP::respond 301 Location $rdr_target"
Fri Nov 23 04:06:04 GMT 2012 err local/tmm3 tmm3[6833] 01220001 TCL error: goRedirects - Operation not supported. Multiple redirect/respond invocations not allowed (line 17) invoked from within "HTTP::respond 301 Location "http://blabla/vod/page/default/home.do""
Fri Nov 23 04:06:04 GMT 2012 err local/tmm tmm[6830] 01220001 TCL error: goRedirects - Operation not supported. Multiple redirect/respond invocations not allowed (line 11) invoked from within "HTTP::respond 301 Location $rdr_target"
Fri Nov 23 04:07:46 GMT 2012 err local/tmm1 tmm1[6831] 01220001 TCL error: goRedirects - Operation not supported. Multiple redirect/respond invocations not allowed (line 21) invoked from within "HTTP::respond 301 Location $rdr_target"
Fri Nov 23 04:08:23 GMT 2012 err local/tmm3 tmm3[6833] 01220001 TCL error: goRedirects - Operation not supported. Multiple redirect/respond invocations not allowed (line 11) invoked from within "HTTP::respond 301 Location "http://blabla[HTTP::uri]""
The rule:
when HTTP_REQUEST {
log local0. "Found [HTTP::host]"
if { [HTTP::path] equals "/" or [HTTP::path] equals "/vod" } {
HTTP::path "/vod/"
}
set rdr_target [class match -value [HTTP::uri] equals some_uri_redirects]
if { $rdr_target ne "" } {
HTTP::respond 301 Location $rdr_target
log local0. "Found match with value = $rdr_target"
}
if { [HTTP::path] starts_with "/watch" } {
HTTP::respond 301 Location "http://blabla/vod/page/default/home.do"
}
if { [HTTP::host] equals "blabla" } {
log local0. "Found [HTTP::host]"
set rdr_target [class match -value [HTTP::uri] equals someother_uri_redirects]
if { $rdr_target ne "" } {
HTTP::respond 301 Location $rdr_target
log local0. "Found match with value = $rdr_target for blabla"
} else {
if { [TCP::local_port] equals "80" } {
HTTP::respond 301 Location "http://blabla[HTTP::uri]"
} else {
HTTP::redirect "https://blabla[HTTP::uri]"
}
}
}
}
Thanks in advance!
S.
19 Replies
- spankme_86674
Nimbostratus
Well, apparently it cant go to Data Group for the reason I've mentioned: in iRule it has a regexp form, where it triggers for anything that starts with '/watch', like '/watch', '/watch/' but also '/watch/anything' and so on. It seems that in data group it can only match exactly that, what's used as a string, unless there is a trick to turn it into the same regexp as in iRule. - What_Lies_Bene1
Cirrostratus
The string name or value must match exactly only with what you are comparing it to. So using 'class match [HTTP::uri] starts with "/watch"' would match /watch and /watch/this. As long as /watch is matched it's all good. The operator used and the variable are what matter. Does that make sense? - spankme_86674
Nimbostratus
Yes, it perfectly makes sense and I hoped it works that way, but unfortunately my tests are showing that it isnt working like that. What I did was:
1) remove the whole 'if' that does the "/watch" matching
2) place the string "/with" and its redirect into data group
3) test the whole thing by going to http://blabla/watch - works, go to http://blabla/watch/ - works, go to http://blabla/watch/bla - doesnt work. The last test was working in original setup, and is required to work in the data group scenario, but it seems that the starts_with clause in iRule does additional magic allowing to match with stuff after "/watch/", like "/watch/whatever/else"
Any ideas why? - What_Lies_Bene1
Cirrostratus
I'm out of ideas I'm afraid, sorry. Perhaps someone else who's able to test this can help out? - hoolio
Cirrostratus
If you have "/watch" as a key in a data group named some_uri_redirects and do a lookup of "/watch", "/watch/", "/watch/something/else", or anything else that starts with "/watch" using [class match -value [HTTP::uri] starts_with some_uri_redirects], the command will return the key's value.
If you're seeing something different, can you post a sanitized copy of the iRule and data group?
Thanks, Aaron - Can anyone tell me what the behavior is when you try to do multiple redirects? It errors but what does it actually do?
I am having an issue that I can hardly reproduce but I get complaints about. The issue is that when someone types in an address in Internet Explorer 8 or 9, the first result they get is a "Page Cannot be Displayed" (I cannot find any more detailed account of the error... ). If they hit refresh in the browser, the page loads. I can see in the ltm log that they are hitting the LTM and we are getting the multiple redirect not allow error. So I'm trying to figure out if these two are connected. In other browsers the error does not affect the page from loading. - What_Lies_Bene1
Cirrostratus
I don't know the answer I'm afraid but I can help remove the error perhaps if you'd like to post the iRule? - spark_86682Historic F5 AccountA Tcl error in an iRule (such as the multiple redirect error you're reporting) will typically reset the connection, so it definitely could be the cause of the "page cannot be displayed" errors.
- Thomas_Schaefer
Nimbostratus
Greetings all: I have been cleaning up my redirects to make sure I do not redirect if the connection had already been redirected. I do see the advice to combine iRules but I refuse to make a monolithic mess versus modular iRules (the programmer in me :) ).
That being said, I have resorted to the following arrangement (and much of this comes from other tips I have read on this fantastic reference, DevCentral...)
Any iRule that has a redirect, I do the following as the first line in the HTTP_REQUEST event:
if {$gRespondOrRedirect}{ return };
Then, any iRule that does a respond or redirect, I do the following (the 500 is just one example):
set gRespondOrRedirect 1 HTTP::respond 500 noserver return
This makes sure that future iRules can test $gRespondOrRedirect and return if necessary. The return after the respond is necessary or the same iRule will keep running.
There may be other ways to do this, but that is what I came up with here. Note it occurs to be a New Feature Suggestion might be in order. With a couple small additions to the engine, the following might be possible:
In any iRule that does a redirect:
if {[HTTP::redirected]} { return };
Then, in the actual respond or redirect, the following might help:
HTTP::respond 500 noserver with_return
with_return could be an option to the respond and redirect command to return from the current script at the time of the return.
Of course, engineering gets to decide the validity of something like that to make sure it has general customer usefulness and does not break anything, but I thought I would see what the community thinks before I ask. Is there a better to accomplish this?
Thanks,
Tom Schaefer
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
