Forum Discussion
Russell_E_Glaue
Nimbostratus
Feb 18, 2009How to disable iRule processing on keep-alive per request when using HTTP::respond
How to disable iRule processing on keep-alive per request when using HTTP::respond
Okay, I have encountered a problem I cannot figure out how to get around.
Here is what I want to do:
1) First of all I want to keep the keep-alive connection open - I do not want to close it.
2) The web user connects to the IP for a web site and sends a request
3) the iRule catches something in the request, and send back a response via "HTTP::respond"
4) the iRule execute "event HTTP_REQUEST disable" to stop further iRule processing (important) of HTTP_REQUEST.
5) the keep-alive connection remains open
6) some how the iRule processing is enabled again for the HTTP_REQUEST event.
7) on the next web user's http request, the same iRule(s) is processed.
How do I do this?
*) I do not see how 6 can be possible, while keeping the keep-alive connection open, from everything I have read about how iRules work.
When we use HTTP::respond, the HTTP_RESPONSE event is never processed in the iRules (which is where it has been recommended to execute the "event enable" command), plus I do not see any other events being processed.
My question may be, how can I reenable the HTTP_REQUEST event for the next request on the same keep-alive connection?
But perhaps it should be, how do I turn off iRule processing on a per-request basis when using HTTP::respond?
My goal is to:
1) use the HTTP::respond - immediately returning the response to the web user
2) keep the keep-alive connection open
3) do not process any further iRules
4) allow the web user to send another request on the same keep-alive connection.
5) have the iRules process the new request coming across the same keep-alive connection from the web user.
6) be able to go back to 1 and continue this loop indefinitely.
What does NOT work:
1) the "return" command - it returns, but further iRules are still processed.
2) the "event disable" command - it disables iRules for any future events on the same keep-alive connection, and if you use HTTP::respond, then you have no opportunity to execute "event enable" at the end of the request so iRules will process the next request.
3) the "reject", "TCP::close", or other commands that close the keep-alive connection - I do not want to close the connection.
4) using global variables as flags for determining it further iRules should be processed - according to this article ( http://devcentral.f5.com/Default.aspx?tabid=63&articleType=ArticleView&articleId=236 ) "a global variable ... [is] shared by all connections"
Would anyone know what I can do to resolve this?
-RG
18 Replies
- hoolio
Cirrostratus
Hi RG,
Once you disable the HTTP_REQUEST event it will stay disabled on that TCP connection until it's re-enabled or the connection is closed. The only thing I can think of to allow you to bypass the logic of the other iRule(s) would be to set a local variable in the primary rule. The local variable is specific to that TCP connection so you don't have to worry about trampling with global variables between connections. The other rules can then check that local variable to see whether the code in the secondary rule(s) should be run.
Aaron - Russell_E_Glaue
Nimbostratus
Using local variables - Can you provide an example, because I tried a local variable and it did not work.
Here is my test for using a local variable:irule firstirule { when HTTP_REQUEST priority 10 { set localVar "somevalue" } } irule secondirule { when HTTP_REQUEST priority 100 { if { not [info exists $localVar] } { log local0.err "Variable localVar not available. Initialized in iRule firstirule." } } }
When I run code like this, I get the log message every time.
When I try to access the localVar variable in secondirule anyway, I get an error message.
-RG - hoolio
Cirrostratus
info exists expects the variable name without the $:
info exists localVar
or
info exists ::globalVar
I'd suggest setting it on every request though (either to 0 or 1) depending on whether you want the other iRules' HTTP_REQUEST event code to run. That ensures that the variable is in the correct state on each request on the same TCP connection. I suppose the other option would be to unset the variable instead of setting it to 0 and then checking to see if it's defined in other rules.
Aaron - Russell_E_Glaue
Nimbostratus
Okay,
Is there any better way to do this without putting this code in for every iRule event:rule any_irule { when ?event? { if { not $stop_processing_irules_flag } { normal iRule code } } } - hoolio
Cirrostratus
Not that I can think of. Anyone else have any ideas?
I tried disabling HTTP_REQUEST and then re-enabling the event in HTTP_REQUEST with a priority of 501, but the 501 instance never runs after the HTTP_REQUEST event is disabled:when HTTP_REQUEST { log local0. "500 disabling" event HTTP_REQUEST disable log local0. "500 disabled" } when HTTP_REQUEST priority 501 { log local0. "501?" }
Log output:
: 500 disabling
: 500 disabled
So the answer on that is no. I didn't think it would actually work, but that was the only other thing I could think of. It might be nice if you could do something like this:
event HTTP_REQUEST priority 500 disable
Aaron - Russell_E_Glaue
Nimbostratus
I was actually thinking of a few new feature possibilities.
Currently the format for the event command is:event [] [enable|disable] | [enable all|disable all]
(1)
The first idea is to change this to:event [] [enable|disable] | [enable all|disable all] [forthisconnection|forthisrequest]
Adding the option to say:
event disable all forthisrequest
or
event HTTP_REQUEST disable forthisrequest
The default would be forthisconnection, which is the current action - to disable events for the remainder of the connection.
(2)
The second idea is to change it to:event [] [enable|skip|disable] | [enable all|disable all]
Add the option to say:
event skip all
or
event HTTP_REQUEST skip
which would skip the remainder of the event(s), until the event is completed.
Since I must conclude there is no good way to do what I am wanting, I would really like to add something like this as a feature request.
-RG - Russell_E_Glaue
Nimbostratus
Actually the second suggestion is probably better as:event [] [enable|disable|end] | [enable all|disable all]
So when saying something like:
event HTTP_REQUEST end
or
event end all
Would cause the named event, or all events, to end immediately.
This would also mean that if you want to stop iRule processing, you have to add in the return command so you exit out of the current iRule.
Also, I like your suggestion, skipping ahead to a different priority level.
That is like a 'goto' command.
I have read how from one iRule we can cause the execution of another iRule.
That seems like a possibility to solve this issue, however, I hate the idea of chaining (stacked) iRules together from inside the code.
-RG - spark_86682Historic F5 AccountThe only better thing I can think of is to do a return if that flag is set.
Something like:rule first_rule { when HTTP_REQUEST { set stop_processing 0 if { $condition } { HTTP::respond "foo" set stop_processing 1 } } } rule second_rule { when HTTP_REQUEST { if { $stop_processing } { return } do other stuff here } }
It looks a bit cleaner, IMO. I think that's about the best you can do. - Russell_E_Glaue
Nimbostratus
Yes, but I'd like to avoid doing the "if" clause.
We have over 120 different web site, and they all use various iRules. I have tried hard to consolidate iRules so make everything uniform, and I think I have done a good job. But a lot of iRules are still sharing among virtual servers.
So using "if" is going to complicate a lot.
I am experimenting with different ways of stacking iRules now, using priority levels, to see if I can do anything similar.
I still prefer something better like:
event
Sot the event ends, but the event is not disabled.
-RG - hoolio
Cirrostratus
Hi RG,
Spark is a developer with F5, so he can provide very good feedback. But if you want to create an official request for enhancement, you should open a case with F5 Support.
Aaron
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
