Forum Discussion
How to filter within iRule for HTTP_RESPONSE
Hi all,
Is there anyway we can use an iRule to filter a HTTP_RESPONSE with whats in the HTTP header or something like that? We current use a filter like:
when HTTP_RESPONSE { if {[LB::server pool] contains "xxxxxxxxxxx"}{
This works great but can i then filter deeper, with something like:
elseif {[LB::server pool] contains "xxxxxxxx"}{
switch -glob [HTTP::header Location] {
"xxxx" {
This inst currently working.
Im essentially trying to differentiate a HTTP RESPONSE sent from the same pool.
Thanks!
10 Replies
- Hannes_Rapp
Nimbostratus
Hi Ketzuken,
Is the value of "Location" header you're trying to use in your conditional switch statement? If so, try to replace
withswitch -glob [HTTP::header "Location"]
.switch -glob [HTTP::header value "Location"]Additionally, you may find it useful to include a log statement for the duration of troubleshooting and testing.
. If this log statement returns an empty value tolog local0. "[HTTP::header value "Location"]"
, you'll know the "Location" header was not included in the HTTP response./var/log/ltm - Kevin_Stewart
Employee
If I may add,
You can actually omit the "value" argument if the header name doesn't collide with any of the HTTP::header subcommands. So in most cases:
HTTP::header Locationwill produce the same result as
HTTP::header value LocationBut more important, the Location response header is only ever present in a 30x redirect response. It may simply be that you're looking for the Location header in non-redirect traffic.
- Chris1269_13050
Nimbostratus
Hi and thanks for the response. So it may have been misleading I'm not sure if Location is best thing to filter on. We are filtering the RESPONSE initially with the Pool. We then need to filter deeper into the response and differentiate between two URIs coming from the same POOL in the RESPONSE but i have no idea how to do this.
- Kevin_Stewart
Employee
We then need to filter deeper into the response and differentiate between two URIs coming from the same POOL in the RESPONSE
What if anything is different between the responses from either pool member?
- Chris1269_13050
Nimbostratus
Something like:
elseif {[LB::server pool] contains XXX_POOL"}{ HTTP::header replace Location [string map -nocase {"XXX" "uat_XXX"} [HTTP::header Location]] HTTP::header replace Set-Cookie [string map -nocase {"/XXX" "/uat_XXX"} [HTTP::header Set-Cookie]] STREAM::expression {@XXXB@uat_XXX@} STREAM::enable }Now throw another one into the mix coming from the same Pool. Like: uat_XXX1. So i guess the differences are the Location, but it doesnt appear to be working with that.
- Kevin_Stewart
Employee
My point is that not all responses will contain a Location header - only redirect responses. Unless you're specifically looking for a redirect response, you need to find something else that differentiates the responses of the two pool members. Could you elaborate on what you're trying to do?
- Chris1269_13050
Nimbostratus
That actually makes sense and would explain why what im seeing in Fiddler. The setup we have is very complex. All backend webservers are setup with the same directory names, databases etc... So we are ripping out the 'uat' parts,
1) Within the Request we have:
elseif {$uri contains "/uat_xxx"}{ switch -glob [string tolower [HTTP::uri]] { "*uat_xxx_DB" { pool POOL1 HTTP::header remove "Accept-Encoding" HTTP::header replace Location [string map -nocase {"uat_xxx_DB" "xxx_DB"} [HTTP::header Location]] HTTP::uri [string map -nocase {"uat_xxx_DB" "xxx_DB"} [HTTP::uri]] STREAM::disable } "uat_xxx"*" { pool POOL1 HTTP::header remove "Accept-Encoding" HTTP::header replace Location [string map -nocase {"uat_xxx" "xxx"} [HTTP::header Location]] HTTP::uri [string map -nocase {"uat_xxx" "xxx"} [HTTP::uri]] STREAM::disable } } }So two different URIs going to the same pool with a uri / http header modification
2) So with the response, we need to convert the header and the stream back to what the user sees. How would i go about doing this? As you mentioned i cant use Location as it wont convert it all back (only the redirect responses). I can get it working with one URI in play as all i would have to do is use something like in the Response:
elseif {[LB::server pool] contains "POOL1"}{But as you can see from my request, 2xURIs are using the same pool so i cant use the above. I have attemped to filter on a custom header i inserted within the request but running into the same problems.
I hope this helps!
- Kevin_Stewart
Employee
Well, there might be a few ways to do this.
-
If you can modify the application(s) to throw in some specific response header or maybe metatag, you can filter on that in the response.
-
In most cases the HTTP request and response are an atomic pair, so:
when HTTP_REQUEST { set flag "" if { something } { set flag "true" } elseif { something_else } { set flag "false" } } when HTTP_RESPONSE { if { [info exist flag] } { switch $flag { "true" { do something } "false" { do something_else } } } }
-
- Chris1269_13050
Nimbostratus
Thanks for the help. Using flags in a similar way you suggested worked perfectly. How does this technially work within the iRule and how does the flag persist between request and response?
- Kevin_Stewart
Employee
It's based on the somewhat atomic relationship of an HTTP request and corresponding response of an otherwise stateless protocol. This isn't always the way it worked, especially with certain types of multiplexing, but it generally works well. It's also important to point out that variables exist within the span of a single TCP session, and in most cases the response to a request is in the same TCP session. Again, that's not the case in every environment.
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
