Forum Discussion
Devonion_22138
Nimbostratus
May 14, 2012Redirect to test server and rewrite returned links
I'm trying to write an irule so that I can use a cloned live webserver to test a PHP upgrade.
irule basically changes host header from www.dev.ourserver.com to www.ourserver.com and this part works fine if I only include the HTTP_REQUEST section.
However, when I try to add the HTTP_RESPONSE and HTTP_RESPONSE_DATA sections, I start getting "server hangup"s.
Any help would be most appreciated.
My irule is as follows
when HTTP_REQUEST {
set DEBUG 1
if { [HTTP::version] equals "1.1" } {
if { [HTTP::header is_keepalive] } {
HTTP::header replace "Connection" "Keep-Alive"
HTTP::header remove Accept-Encoding
}
HTTP::version "1.0"
set collected 0
}
if { [HTTP::host] equals "devserverurl"} {
HTTP::header replace "Host" "serverurl"
if { $DEBUG } { log local0. "irule used by IP: [IP::client_addr] - requesting [HTTP::host][HTTP::uri]" }
}
}
when HTTP_RESPONSE {
Get the content length so we can request the data to be
processed in the HTTP_RESPONSE_DATA event.
set DEBUG 1
if { [HTTP::header exists "Content-Length"] } {
set content_length [HTTP::header "Content-Length"]
} else {
set content_length 0
}
content_length of 0 indicates chunked data (of unknown size)
if { $content_length > 0 && $content_length < 1024001 } {
set collect_length $content_length
} else {
set collect_length 1024000
}
if { $DEBUG } {
log local0. "[IP::client_addr]:[TCP::client_port]: Content Length:: $content_length Collect Length: $collect_length"
}
if { $collect_length > 0 } {
HTTP::collect $collect_length
}
}
when HTTP_RESPONSE_DATA {
set DEBUG 1
regsub -all "serverurl" [HTTP::payload] "devserverurl" newdata
if { $DEBUG } {
log local0. "PAYLOAD before replace: [HTTP::payload]"
}
HTTP::payload replace 0 $content_length $newdata
if { $DEBUG } {
log local0. "PAYLOAD after replace: [HTTP::payload]"
}
HTTP::release
if { $content_length > 0 } {
for unchunked data, calculate the remaing length & re-collect if necessary
the HTTP_RESPONSE_DATA event will be triggered again when each collection is complete
set collect [expr {$collected + $collect_length}]
set remaining [expr {$content_length - $collected}]
if { $remaining > 0 } {
if { $remaining < $collect_length } {
set collect_length $remaining
}
HTTP::collect $collect_length
}
} else {
chunked responses data, continue collecting in 1MB chunks. Watch for hanging responses here.
The HTTP_RESPONSE_DATA event will be triggered again when each ccollection is complete
HTTP::collect $collect_length
}
}Many Thanks
6 Replies
- Devonion_22138
Nimbostratus
Sorry,
I'd just like to add that if I create a very simple staic html page with just a link in there to make sure it gets rewritten this works, so it seems the issues is with more complex pages. - Michael_Yates
Nimbostratus
Hi Devonion,
Have you considered using a Stream Profile?
This can be done with the default LTM Stream Profile or via an iRule that uses the STREAM::expression, STREAM::enable, and STREAM::disable commands.
This is the methodology that is used where I work to allow the same production code to be promoted through the test environments without being changed, but allows the different environment URL's to be modified on the fly.
Hope this idea helps. - Devonion_22138
Nimbostratus
Hi Michael,
My first attempt actually used the STREAM::expression - but I seemed to get inconsistent results - it seemed to work one minute, then pressing CTRL-F5 to reload page in a brower and it didn't rewrite the links. Basically I did the same as the irule above in the HTTP_REQUEST, but added a STREAM::disable at the start. Then did a STREAM::match and finally the STREAM::expression and STREAM::enable (I think)
If I still have a copy of the irule I will post tomorrow.
However, I guess I should try the default STREAM profile as that seems the simplest way to go, but I inherited this F5 and I'm not 100% sure what was there by default and what custom additions I've inherited - and this is all new to me and of course this needed sorting yesterday! So I've not got as much knowledge as I'd like before I've had to just dive in.
I appreciate the reply, thanks! - Devonion_22138
Nimbostratus
OK, so I went back to the drawing board, read some more and realised I was completely over complicating things here.
I kept my http_request section to rewrite the header, works as expected.
I then did as you suggested and used the default STREAM profile and this now works a treat.
So!! Last piece of the puzzle is a valid replace command in the target of my stream profile.
I've left the source empty and in the target I've added @www.ourserver.com@www.dev.ourserver.com@
Now this is great for testing, but we have loads of Virtual Hosts, some with different domains and so I need a regex
I tried the following but could not save the profile due to an error about it being bad
It works in sed, but I know only basic regex is supported in the stream profile, but I thought this was pretty basic.
This is a simplified version but syntax is same as my target.
@www\(.*\).com@www.dev\1.com@
Is this sort of substitution possible in the stream profile? I get "bad regular expression in stream" error when I try to save this.
Thanks - Michael_Yates
Nimbostratus
Hi Devonion,
Take a look here and see if this helps you:
LTM stream profile: Multiple replacements & regular expressions
Hope this helps - Devonion_22138
Nimbostratus
Hi Michael,
That link is where I got the information I needed to get this working - unfortunately, it seems like backreferences are not supported in the stream profile :(
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
