Forum Discussion
Moe_Jartin
Cirrus
Jan 05, 2009Context Root Masking/URL Rewrite and pool selection
I have an existing iRule that simply selects poolA based on a list of URIs, everything else goes to poolB.
when HTTP_REQUEST {
switch -glob [string tolower [HTTP::uri]] {
/contextroot* -
/front* -
/static* -
/css* -
/flash* -
/images* -
/jsimages* -
/xml* -
/xsl* -
/vgn-ext-templating* -
/ -
/script/\* -
/interpret* -
/disabilit* -
/shared* {
pool pool_A
}
default {
pool pool_B
}
}
}
I have now been tasked with masking the "contextroot" so that the browser does not see it but it is still passed to the server. i.e. browser sends request to www.mysite.org/blah/blah/... and I rewrite to /contextroot/blah/blah/... There are several different variables that "blah" could be but, it IS a defined list. So i am thinking of using a stream profile with a class list. here is a first shot at just the context root masking piece, i'll add the rest of the existing rule later.
set OriginalURI HTTP::uri
when HTTP_REQUEST {
if {[matchclass [[string tolower [HTTP::uri]] starts_with $::maskedURIs]} { << STREAM::expression "@$OriginalURI@/contextroot/$OriginalURI@" <<<< Can I use the variable inside the stream expression??
STREAM::enable
pool poolA
}
}
when HTTP_RESPONSE {
if {[[HTTP::status] == 200] and [[HTTP::header value "Content-Type"] contains text]} {
STREAM::expression "@/contextroot@@"
STREAM::enable
}
}
Anyone see anything worng with this or know a better way to do it???
4 Replies
- hoolio
Cirrostratus
You should only need to change the path in the request. You can do this with HTTP::path instead of a stream filter (which would modify the request payload):Prepend /contextroot to the original path HTTP::path "/contextroot[HTTP::path]"
For the response, are you sure non-200 responses won't ever contain the /contextroot? You should also explicitly disable the stream filter if the condition(s) aren't met:when HTTP_RESPONSE { if {[[HTTP::status] == 200] and [[HTTP::header value "Content-Type"] contains text]} { STREAM::expression "@/contextroot@@" STREAM::enable } else { Disable the stream filter STREAM::disable } }
Also, you can use variables in a stream expression as long as you wrap the expression with double quotes (like you did) instead of curly braces.
Aaron - Moe_Jartin
Cirrus
Aaron,
Thanks for the response. So this is what I have, tying in the original rule:
when HTTP_REQUEST {
Prepend /contextroot to masked URIs and send to poolA
if {[matchclass [[string tolower [HTTP::uri]] starts_with $::maskedURIs]} {
HTTP::path "/contextroot[HTTP::path]"
pool poolA
Send other URIs thru original "switch -glob"
} else {[switch -glob [string tolower [HTTP::uri]]} {
/contextroot* -
/front* -
/static* -
/css* -
/flash* -
/images* -
/jsimages* -
/xml* -
/xsl* -
/vgn-ext-templating* -
/ -
/script/\* -
/interpret* -
/disabilit* -
/shared* {
pool pool_A
}
default {
pool pool_B
}
}
when HTTP_RESPONSE {
Remove /contextroot from HTTP responses
if {[[HTTP::header value "Content-Type"] contains text]} {
STREAM::expression "@/contextroot@@"
STREAM::enable
} else {
STREAM::disable
}
}
I removed the 200 response requirement. I had origianlly added it so as not to overwrite 301 or 302 redirects that might happen to have that in it but I guess I should be overwriting those anyway.
I will run this on my test box and see if it works. Thanks Again!!!
Joe - Moe_Jartin
Cirrus
OK so new requirement... On the HTTP_RESPONSE I need to only remove the /contextroot for the masked URIs. I initially thought to try:
if {[matchclass [[string tolower [HTTP::uri]] starts_with $::maskedURIs] and [[HTTP::header value "Content-Type"] contains text]}
STREAM::expression "@/contextroot$::maskedURIs@@"
STREAM::enable
but then I realized that HTTP::uri would only catch the headers and NOT the body, if it worked at all. It there a way to search the HTML response for /contextroot/$::maskedURIs and then remove just the /contextroot ??? - hoolio
Cirrostratus
Once you add an HTTP profile to a VIP, a stream profile will only operate against the HTTP payload (not the HTTP headers). The response doesn't contain a URI exactly. A 30x redirect could contain a URL with the contextroot. You could use 'HTTP::header replace Location $new_value' to do this. Here is an example (Click here).
How many masked URI's are there? You could possibly read the masked URIs from the class and build a stream expression for each one, but I could see it being resource intensive if there are more than a few. Here is a quick example:when RULE_INIT { The prefix to remove set ::uri_prefix "/contextroot" A fake datagroup (actually a list) to test with set ::masked_uris [list /uri1 /uri2 /uri3 /uri4] Initialize a variable to test with. This would be used to set the stream expression: STREAM::expression $stream_expression set stream_expression "" Loop through each element in the "datagroup" foreach uri $::masked_uris { Log the current element log local0. "\$uri: $uri" Append the current URI to the stream expression set stream_expression "$stream_expression @$::uri_prefix$uri@$uri@" Log the current stream expression log local0. "\$stream_expression: $stream_expression" } Log the final result for the stream expression log local0. "\$stream_expression: $stream_expression" }
And the log output:
Rule : $uri: /uri1
Rule : $stream_expression: @/contextroot/uri1@/uri1@
Rule : $uri: /uri2
Rule : $stream_expression: @/contextroot/uri1@/uri1@ @/contextroot/uri2@/uri2@
Rule : $uri: /uri3
Rule : $stream_expression: @/contextroot/uri1@/uri1@ @/contextroot/uri2@/uri2@ @/contextroot/uri3@/uri3@
Rule : $uri: /uri4
Rule : $stream_expression: @/contextroot/uri1@/uri1@ @/contextroot/uri2@/uri2@ @/contextroot/uri3@/uri3@ @/contextroot/uri4@/uri4@
Rule : $stream_expression: @/contextroot/uri1@/uri1@ @/contextroot/uri2@/uri2@ @/contextroot/uri3@/uri3@ @/contextroot/uri4@/uri4@
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
