Forum Discussion
12 Replies
Hi Ciao,
this error would happen if a previous rule had already responded the request and you try to respond a second time to the very same request. The return command unfortenately doesn't stop the processing of following iRules...
You may either combine those rules into a single one and then
the script after eachreturn
...[HTTP::respond]
when HTTP_REQUEST { if { [string tolower [HTTP::path]] equals "/something.txt" } { HTTP::respond 200 content "User-agent: * \nDisallow: /somretyhing.pe \nAllow: /" return } if { [string tolower [HTTP::path]] equals "/somethingother.txt" } { HTTP::respond 200 content "User-agent: * \nDisallow: /somretyhing.pe \nAllow: /" return } }
... or you may inform the later iRules that the request is already responded...
when HTTP_REQUEST { set already_responded 0 if { [string tolower [HTTP::path]] equals "/something.txt" } { HTTP::respond 200 content "User-agent: * \nDisallow: /somretyhing.pe \nAllow: /" set already_responded 1 return } } when HTTP_REQUEST { if { $already_responded } { do nothing } else { if { [string tolower [HTTP::path]] equals "/somethingother.txt" } { HTTP::respond 200 content "User-agent: * \nDisallow: /somretyhing.pe \nAllow: /" return } } }
Note: Keep in mind to trigger a
in the first iRule to initialize/reset the variable.set already_responded 0
A third option would be to see if a response is already send to the client by trying to minipulate the REQUEST or RESPONSE headers and [catch] the error which would happen if a response is already send. But this could have a certain performance impact.
when HTTP_REQUEST { if { [catch {HTTP::payload replace 0 0 {}}] } then { do nothing } else { if { [string tolower [HTTP::path]] equals "/something.txt" } { HTTP::respond 200 content "User-agent: * \nDisallow: /somretyhing.pe \nAllow: /" return } } } when HTTP_REQUEST { if { [catch {HTTP::payload replace 0 0 {}}] } then { do nothing } else { if { [string tolower [HTTP::path]] equals "/somethingother.txt" } { HTTP::respond 200 content "User-agent: * \nDisallow: /somretyhing.pe \nAllow: /" return } } }
Cheers, Kai
- Hannes_Rapp
Nimbostratus
Assuming all your iRules are the same as your sample, replace
withreturn
function in all iRules that invoke redirects or responses. The return function is not needed here. The event disable function should be called after each redirect or response statement, unless you merge the iRules together so that this particular TCL error can no longer occur. By doing so, you may also want to look into iRule execution priorities to make sure no important functionality is superseded.event disable
https://devcentral.f5.com/questions/stop-processing-irule-s-if-condition-is-met
- Hey Hannes, as far as I know "event disable" is persistent to the TCP connection. So it would cause keep-alive'ed connections to not trigger the HTTP_REQUEST events on the very next request. Isn't it? Cheers, Kai
- Hannes_Rapp
Nimbostratus
Indeed, but if needed, you can also add a 'TCP::close' function after the 'event disable' function, to eliminate any possibility of problems with long sessions. A new TCP handshake (and possible SSL handshake) after each F5-initiated HTTP response or redirect should not be a performance hazard. You can achieve the same by appending a 'Connection Close' flag with your HTTP::respond functions. Yet another possibility is conditionally re-enabling the HTTP_REQUEST event, but i'd just prefer closing down on the TCP level for simplicity. - Hi Hannes, thanks for confirming. So nothing has changed since then... :-( BTW: Did you already tried to use LTM Policies to reenable events on every single request? Could be an option now, or isn't it? Cheers, Kai
- Hannes_Rapp_162
Nacreous
Assuming all your iRules are the same as your sample, replace
withreturn
function in all iRules that invoke redirects or responses. The return function is not needed here. The event disable function should be called after each redirect or response statement, unless you merge the iRules together so that this particular TCL error can no longer occur. By doing so, you may also want to look into iRule execution priorities to make sure no important functionality is superseded.event disable
https://devcentral.f5.com/questions/stop-processing-irule-s-if-condition-is-met
- Hey Hannes, as far as I know "event disable" is persistent to the TCP connection. So it would cause keep-alive'ed connections to not trigger the HTTP_REQUEST events on the very next request. Isn't it? Cheers, Kai
- Hannes_Rapp_162
Nacreous
Indeed, but if needed, you can also add a 'TCP::close' function after the 'event disable' function, to eliminate any possibility of problems with long sessions. A new TCP handshake (and possible SSL handshake) after each F5-initiated HTTP response or redirect should not be a performance hazard. You can achieve the same by appending a 'Connection Close' flag with your HTTP::respond functions. Yet another possibility is conditionally re-enabling the HTTP_REQUEST event, but i'd just prefer closing down on the TCP level for simplicity. - Hi Hannes, thanks for confirming. So nothing has changed since then... :-( BTW: Did you already tried to use LTM Policies to reenable events on every single request? Could be an option now, or isn't it? Cheers, Kai
- Caio_178191
Nimbostratus
Thank you all for the answers. I will do tests here and when have answers I will let u know.