Forum Discussion
Frank_J_104756
Oct 31, 2007Historic F5 Account
HTTP::payload replace
I have 2 needs...1 to replace/hide the server in the http redirects that are being sent by the node. 2) to replace/hide the server in the actual content.
when HTTP_RESPONSE {
if { [LB::server addr] eq "10.1.1.1" } {
HTTP::header replace Location [string map { } [HTTP::header Location]] }
elseif { [LB::server addr] eq "10.1.1.2" } {
HTTP::header replace Location [string map { } } [HTTP::header Location]] }
}
the irule above works great for the redirects but not for the content / payload. When I read up on the HTTP::payload command though it's specifying offset or begin point and I won't know that because the servername will appear different on different pages.
Any suggestions ? I'd love to do a HTTP::payload replace with a findstr if possible but they way I read the wiki for HTTP::payload replace I can't.
Oh, and by the way, using stream profile isn't working. I have a separate support case open for that. I would have preferred to use stream but for some reason it ain't working whereas the irules are.
thanks!!!
17 Replies
- hoolio
Cirrostratus
There is an example showing how to replace a string in a payload on the HTTP::payload page (Click here) which uses regsub -all. I suppose you could use string map for a more efficient replacement if don't need a regex to describe the search string(s).
Something like this...?when HTTP_RESPONSE { if { [HTTP::header exists "Content-Length"] } { set content_length [HTTP::header "Content-Length"] } else { set content_length 1000000 } if { $content_length > 0 } { HTTP::collect $content_length } } when HTTP_RESPONSE_DATA { regsub -all "oursite" [HTTP::payload] "oursitedev" newdata log "Replacing payload with new data." HTTP::payload replace 0 $content_length [string map {oursite oursitedev} [HTTP::payload]}] HTTP::release }
Out of curiosity, do you have any idea of why the stream profile isn't working? What version are you running?
Aaron - Frank_J_104756Historic F5 Accountthey're running 9.4.1 HF1...let me try your solution, Thanks by the way!!!...I'll post back if it works...I do have a support case open on the stream profile..so far the feedback I've gotten after they checked the tcpdumps, qkview, and httpwatch captures is the stream profile should have worked and it's being escalated to see why it isn't...
- Frank_J_104756Historic F5 Accountso irule now looks like
when HTTP_RESPONSE {
if { [LB::server addr] eq "10.0.19.50" } {
HTTP::header replace Location [string map {nwte1jas7:8882 bob} [HTTP::header Location]]
log "replacing nwte1jas7:8882 in header with bob" }
elseif { [LB::server addr] eq "10.0.19.42" } {
HTTP::header replace Location [string map {nwte1jas6:8882 bob} [HTTP::header Location]]
log "replacing nwte1jas7:8882 in header with bob" }
if { [HTTP::header exists "Content-Length"] } {
set content_length [HTTP::header "Content-Length"] }
else {
set content_length 1000000 }
if { $content_length > 0 } {
HTTP::collect $content_length }
}
when HTTP_RESPONSE_DATA {
if { [LB::server addr] eq "10.0.19.50" } {
regsub -all "nwte1jas7:8882" [HTTP::payload] "bob" newdata
log "Replacing nwtejas7:8882 with bob in the payload."
HTTP::payload replace 0 $content_length [string map {nwte1jas7:8882 bob} [HTTP::payload]]
HTTP::release }
elseif { [LB::server addr] eq "10.0.19.42" } {
regsub -all "nwte1jas6:8882" [HTTP::payload] "bob" newdata
log "Replacing nwtejas6:8882 with bob in the payload."
HTTP::payload replace 0 $content_length [string map {nwte1jas7:8882 bob} [HTTP::payload]]
HTTP::release }
}
I'm seeing error in log shown below
TCL error: Rule jas_redirect2 HTTP_RESPONSE_DATA - Out of bounds line 1 invoked from within HTTP::payload replace 0 $content_length [string map {nwte1jas7:8882 bob} [HTTP::payload]] - hoolio
Cirrostratus
From the wiki page and Deb's post (Click here), it looks like you need to use the original content length (what's been collected so far). LTM should then recalculate the new length and update the Content-Length header it sends (in 9.4.0 and later).
As $content_length should be the amount of bytes collected so far, I'm not sure why you're seeing the out of bounds error.
Anyone have ideas on this?
Thanks,
Aaron - Frank_J_104756Historic F5 AccountI think I'm getting the out of bounds because there is no content length set w/in the original http header...so the irule is using 10000 when the content may only be 100,200, etc...
- hoolio
Cirrostratus
Ah. Can you try this then?
HTTP::payload replace 0 [HTTP::payload length] [string map {nwte1jas7:8882 bob} [HTTP::payload]]
Aaron - Frank_J_104756Historic F5 AccountI get wrong of args for those lines when I do that..
line 28: [wrong args] [HTTP::payload replace 0 [string map {nwte1jas7:8882 bob} [HTTP::payload]]]
line 33: [wrong args] [HTTP::payload replace 0 [string map {nwte1jas7:8882 bob} [HTTP::payload]]] - hoolio
Cirrostratus
There should be '[HTTP::payload length]' after the 0. Also, I think nwte1jas7 should be nwteljas6 is the second HTTP::payload replace command.
Aaron - Frank_J_104756Historic F5 AccountAaron, I'm not getting errors anymore but it appears like none of the HTTP_RESPONSE_DATA section is even running. I put a log entry at the beginning of it to see if I got anything and I didn't. Here's what I have in teh irule now...
when HTTP_RESPONSE {
if { [HTTP::status] starts_with "301" } {
if { [LB::server addr] eq "10.0.19.50" } {
HTTP::header replace Location [string map {nwte1jas7:8882 E1NP.crocs.com} [HTTP::header Location]]
log "replacing nwte1jas7:8882 in header with E1NP" }
elseif { [LB::server addr] eq "10.0.19.42" } {
HTTP::header replace Location [string map {nwte1jas6:8882 E1NP.crocs.com} [HTTP::header Location]]
log "replacing nwte1jas7:8882 in header with E1NP" }
}
}
when HTTP_RESPONSE_DATA {
if { [LB::server addr] eq "10.0.19.50" } {
regsub -all "nwte1jas7:8882" [HTTP::payload] "bob" newdata
log "Replacing nwtejas7:8882 with bob in the payload."
HTTP::payload replace 0 [HTTP::payload length] [string map {nwte1jas7:8882 E1NP.crocs.com} [HTTP::payload]]
HTTP::release }
elseif { [LB::server addr] eq "10.0.19.42" } {
regsub -all "nwte1jas6:8882" [HTTP::payload] "bob" newdata
log "Replacing nwtejas6:8882 with bob in the payload."
HTTP::payload replace 0 [HTTP::payload length] [string map {nwte1jas6:8882 E1NP.crocs.com} [HTTP::payload]]
HTTP::release }
} - hoolio
Cirrostratus
It looks like you removed the HTTP::collect command from the HTTP_RESPONSE event. This is what dictates that LTM should buffer the HTTP data in the response. The HTTP_RESPONSE_DATA event is triggered when the amount of data specified in the HTTP::collect command has been collected.
If there isn't a Content-Length header (like when the server is sending chunked responses) to use in the collect command, you could specify something smaller than one million bytes. Can you add the collect command back in and try with 100?
Does anyone else have ideas on how best to collect response data when there isn't a content length header? If you specify a smaller number of bytes than what is sent, does the HTTP::payload command only return what you've collect? If so, don't you miss the change to perform the replacement in any subsequent response data that wasn't collected?
Aaron
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)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
