Forum Discussion
Frank_Ziebarth_
Nimbostratus
Jun 16, 2006rewrite an URI with a request parameter
Hallo
we have two webservices in the development, so the the uri is change very often.
Our end-user should connect to these server to an easy URI
http://server/portal/
http://server/info/
This is my iRule:
when HTTP_REQUEST {
if {[HTTP::uri] starts_with "/portal/"} {
HTTP::uri "/version02.webservices.portal/"
use pool SDS_Pool01
}
if {[HTTP::uri] starts_with "/info/"} {
HTTP::uri "/version04.webservices.info/"
use pool SDS_Pool02
}
}
It works for
http://server/portal/service.asmx
and
http://server/portal/test/service.asmx
but not for
http://server/portal/service.asmx?op=SignVerifyCompressEmail
In this case it looks like that the iRule cut the part
"?op=SignVerifyCompressEmail"
I can´t understand that, can somebody tell me where my mistake is?
10 Replies
- Terje_Gravvold
Nimbostratus
Hi,
I think your mistake may be that you replace the whole URI with a constant (/version04.webservices.info/). Everything in the URI will be replaced by this. Try to insert a log sentence and explore what happens.
You can solve this with a regsub command or the like. I don't garante the syntax but I hope you get the idea :-).
Example
when HTTP_REQUEST {
if {[HTTP::uri] starts_with "/portal/"} {
log local0. "Original HTTP uri = [HTTP::uri]"
set [HTTP::uri] [regsub -all ^/portal [HTTP::uri] "/version02.webservices.portal"]
log local0. "New HTTP uri = [HTTP::uri]"
use pool SDS_Pool01
}
} - hoolio
Cirrostratus
HTTP::uri refers to the entire URI, including the query string. So when you are setting the URI with HTTP::uri "/version02.webservices.portal/" or HTTP::uri "/version04.webservices.info/", you are overwriting the entire URI.
If you want to replace the instance of /portal/ with /version02.webservices.portal/ and leave the rest of the URI intact, you can use string map:
when HTTP_REQUEST {
if { [HTTP::uri] starts_with "/portal/" } {
HTTP::uri [string map { /portal/ /version02.webservices.portal/ } [HTTP::uri]]
pool SDS_Pool01
}
elseif { [HTTP::uri] starts_with "/info/" } {
HTTP::uri [string map { /info/ /version04.webservices.info/ } [HTTP::uri]]
pool SDS_Pool02
}
}
Aaron - Terje_Gravvold
Nimbostratus
Oh, I didn't know that. I'll remember it for later use. Actually I've wondered about the performance of regexp/regsub compared to their alternatives.
Thanks again. - JRahm
Admin
You can evaluate the cpu performance of either method by turning timing on your rules:timing on when CLIENT_ACCEPTED { ... }
or a specific eventwhen CLIENT_ACCEPTED { ... } when HTTP_REQUEST timing on { ... }
This post by unRuleY details how to interpret the cpu data:
http://devcentral.f5.com/Default.aspx?tabid=28&view=topic&forumid=5&postid=3650
To evaluate memory performance use tmctl mem:[root@bigip:Active] uid tmctl mem name allocs bytes_allocated max_bytes ------------- ------ --------------- --------- rules 3 280 280 tcl 1148 111844 186779 - You can also view the timing statistics (cpu cycles) with the new F5 iRule Editor. Right click on an iRule in the list and select the "Properties" menu item and then select the Statistics tab.
-Joe - Terje_Gravvold
Nimbostratus
Thanks joe and citizen_elah. Your anwers to this post answers all of my wonderings about iRule performance metering. Great stuff! - Frank_Ziebarth_
Nimbostratus
Hallo,
thanks for your fast response.
I use the version from hoolio, it works fine.
I would like extend the iRule with logging
when HTTP_REQUEST {
if { [HTTP::uri] starts_with "/portal/" } {
log local0. "Original HTTP uri = [HTTP::uri]"
HTTP::uri [string map { /portal/ /version02.webservices.portal/ } [HTTP::uri]]
log local0. "New HTTP uri = [HTTP::uri]"
pool SDS_Pool01
}
....
But the logging not work correctly, there is no different between the Original URI and the URI after the rewrite.
tmm tmm[989]: Rule _TEST_Frank : Original HTTP uri = /portal/default.aspx
tmm tmm[989]: Rule _TEST_Frank : New HTTP uri = / portal/default.aspx
Can you help me here again?
Thanks Frank. - hoolio
Cirrostratus
It looks like HTTP::uri only refers to the original client request. Perhaps one of the gurus can explain this.
I used the following to verify the rewrite though:when HTTP_REQUEST { set debug to 1 to enable logging to /var/log/ltm. Set to 0 to disable logging. set debug 1 if { [HTTP::uri] contains "uri1" } { HTTP::uri [string map { uri1 uri2 } [HTTP::uri]] if {$debug}{ log local0. "Rewrote URI from: [HTTP::uri]" log local0. 'Rewrote URI to: [string map { uri1 uri2 } [HTTP::uri]]" } } } - I've see this behavior before as well. Maybe unRuleY could comment on why it is but I've verified that the URI is correctly changed with the HTTP::uri command but the contents of the variable isn't correctly updated to match. Maybe this has something to do with variable caching but I'm not sure. If you want to log the values, store it into a temporary variable.
when HTTP_REQUEST { if { [HTTP::uri] starts_with "/portal/" } { log local0. "Original HTTP uri = [HTTP::uri]" set newUri [string map { /portal/ /version02.webservices.portal/ } [HTTP::uri]] HTTP::uri $newUri log local0. "New HTTP uri = $newUri" pool SDS_Pool01 }
-Joe - Frank_Ziebarth_
Nimbostratus
yes you are right, now it works.
Thanks to all for the help.
Frank
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