Forum Discussion
Bob_10976
Nimbostratus
May 12, 2008iRule re-write to replace ISAPI re-write
Hello all...
We are currently using ISAPI re-write in our portal to re-write uri's to the appropriate location. With the help of this forum I came up with the following, which works fine for /Portal/Category/
when HTTP_REQUEST {
if { [HTTP::uri] starts_with "/Portal/Category/" } {
HTTP::uri "/g2p/KII.G2P.Portal.Web.Pages/Category.aspx?id=[substr [HTTP::uri] 17 "\/"] "
}
}
But my issue is that I have a hundreds of entries in my ISAPI file and not all of them are /portal/category/ some do have the /portal/"somthing differnet", some have a different somthing/something. Obviously I don’t want to create hundreds of iRules or an iRule that has hundreds of “if then else” statements. Does anyone have any other suggestion or thoughts.
Below is a small example of some of the rewrites in my ISAPI file:
RewriteCond Host: test.mysite.com
RewriteRule /Portal/Search\.aspx(.*) /g2p/file.G2P.Portal.Web.Pages.Google/Search.aspx$1 [I]
RewriteCond Host: test.mysite.com
RewriteRule /Portal/SearchProxy\.aspx(.*) /g2p/file.G2P.Portal.Web.Pages.Google/SearchProxy.aspx$1 [I]
RewriteCond Host: test.mysite.com
RewriteRule /Portal/etc/(.*) /g2p/file.G2P.Portal.Web.Pages.Google/etc/$1 [I]
RewriteCond Host: test.mysite.com
RewriteRule /Portal/ExternalLink\.aspx(.*) /g2p/KII.G2P.Portal.Web.Pages/ExternalLink.aspx$1 [I]
RewriteCond Host: www\.test\.mayor\.state\.com
RewriteHeader Host: .* mayor\.state\.com
RewriteCond Host: test\.mayor\.state\.com
RewriteHeader Host: .* mayor\.state\.com
RewriteCond Host: cms\.test\.state\.mayor\.com
RewriteHeader Host: .* mayor\.state\.com
RewriteCond Host: test\.agency\.state\.com
RewriteHeader Host: .* agency\.state\.com
RewriteCond Host: www\.test\.agency\.state\.com
RewriteHeader Host: .* agency\.state\.com
RewriteCond Host: test\.cms\.agency\.state\.com
RewriteHeader Host: .* agency\.state\.com
RewriteCond Host: test\.another_agency\.state\.com
RewriteHeader Host: .* commerce\.state\.com
RewriteCond Host: www\.test\.another_agency \.state\.com
RewriteHeader Host: .* another_agency\.state\.com
RewriteCond Host: cms\.test\.another_agency \.state\.com
RewriteHeader Host: .* another_agency\.state\.com
Thanks in advance…
Bob
14 Replies
- hoolio
Cirrostratus
Hi Bob,
It looks like you're trying to modify what we call the path within the URI, without modifying the query string. In the isapi configuration, you're using regexes with backreferences. In iRules you can do this more efficiently with string commands and/or the default HTTP:: commands (Click here).
For a URL of:
http://www.example.com/path/to/file.ext?param1=value1¶m2=value2
The Host, www.example.com, can be retrieved using HTTP::host (Click here).
You can set the Host header value using 'HTTP::header replace Host newhost.example.com' (Click here)
The path, /path/to/file.ext, can be retrieved or set using the HTTP::path command (Click here)
Most of your rewrite conditions are based on the host header. You can use switch commands to efficiently handle the cases.when HTTP_REQUEST { Log a debug message to /var/log/ltm with the original host and URI. Comment out/remove once done testing. log local0. "[IP::client_addr]:[TCP::client_port]: new request to [HTTP::host][HTTP::uri] (path: [HTTP::path])" switch [string tolower [HTTP::host]] { "test.mysite.com" { Request was to host test.mysite.com, so check the path and do path rewrites log local0. "[IP::client_addr]:[TCP::client_port]: matched test.mysite.com, checking path" switch [HTTP::path] { "/Portal/Search.aspx" { Update path log local0. "[IP::client_addr]:[TCP::client_port]: matched test.mysite.com/Portal/Search.aspx, \ updating path to /g2p/file.G2P.Portal.Web.Pages.Google/Search.aspx" HTTP::path "/g2p/file.G2P.Portal.Web.Pages.Google/Search.aspx" } "/Portal/SearchProxy.aspx" { Update path log local0. "[IP::client_addr]:[TCP::client_port]: matched test.mysite.com/Portal/SearchProxy.aspx, \ updating path to /g2p/file.G2P.Portal.Web.Pages.Google/SearchProxy.aspx" HTTP::path "/g2p/file.G2P.Portal.Web.Pages.Google/SearchProxy.aspx" } "/Portal/etc/" { Update path log local0. "[IP::client_addr]:[TCP::client_port]: matched test.mysite.com/Portal/etc/, \ updating path to /g2p/file.G2P.Portal.Web.Pages.Google/etc/" HTTP::path "/g2p/file.G2P.Portal.Web.Pages.Google/etc/" } "/Portal/ExternalLink.aspx" { Update path log local0. "[IP::client_addr]:[TCP::client_port]: matched test.mysite.com/Portal/ExternalLink.aspx, \ updating path to /g2p/KII.G2P.Portal.Web.Pages/ExternalLink.aspx" HTTP::path "/g2p/KII.G2P.Portal.Web.Pages/ExternalLink.aspx" } } } "www.test.mayor.state.com" { Rewrite Host header HTTP::header replace Host "mayor.state.com" } } } when HTTP_REQUEST priority 501 { This event and code is here just to allow logging of the updated Host and path values These commands returned cached values when executed multiple times in the same event. Log a debug message to /var/log/ltm with the modified host and URI. Remove once done testing. log local0. "[IP::client_addr]:[TCP::client_port]: updated host/uri [HTTP::host][HTTP::uri] (path: [HTTP::path])" }
Aaron - Bob_10976
Nimbostratus
Aaron....Thanks for the reply and example.
I wanted to follow up because using this I will have a huge iRule with a hundreds of those entries. Could that cause latency issues if the rewrite path is near the bottom of the rule, if say I have 500 hundred entries.
If that's the best way then I'll move forward, but I was doing some more research and wanted to know if using functions like findclass and/or matchclass with data groups would be more effective and/or efficient?
Thanks,
Bob - hoolio
Cirrostratus
I think a switch statement is most efficient up to a point (50 - 100 entries?). Beyond that, your idea for classes would probably be more efficient. I don't think either option would add significant latency though.
Do you always want to rewrite the paths regardless of which host header value the request was made with? If so, it would be relatively simple to have one host class and one path class. If you only want to rewrite the path if a specific host is requested, then you could create a class with the "source" and "destination" host and path values, like www.external-host.example.com/external/path/ www.inside-host.example.com/internal/path/.
You might try either using the ProxyPass rule (Click here) or adapting some of the logic from it.
Aaron - Bob_10976
Nimbostratus
Would it be possible for an example of the classes functions, in regards to the ISAPI portion I posted?
Thanks in advance..
Bob - Xin_99652
Nimbostratus
I need change http://mycompany.com/section_one/..... to http://www.mycompany.com/section_one/... can I do it by using iRule? thanks, - hoolio
Cirrostratus
Hi there,
Do you want to redirect all requests made to mycompany.com to the same URI on www.mycompany.com? If so, you can check the host header and redirect requests to mycompany.com:when HTTP_REQUEST { Check host header if {[string tolower [HTTP::host]] eq "mycompany.com"}{ Redirect client to www.mycompany.com with the same URI HTTP::redirect "http://www.mycompany.com[HTTP::uri]" } }
Aaron - Bob_10976
Nimbostratus
My actual rule I'm using...
when HTTP_REQUEST {
if { [string tolower [HTTP::host]] equals "www.mysite.com" } {
HTTP::respond 301 Location http://mysite.com[HTTP::uri]
} - Xin_99652
Nimbostratus
Hi Aaron/BobMc,
many thinks for both of you.
I need change http://mycompany.com/* -> http://www.mycompany/*.
I am going to try both codes.
The question I have for BobMc,
when HTTP_REQUEST {
if { [string tolower [HTTP::host]] equals "www.mysite.com" } {
HTTP::respond 301 Location http://mysite.com[HTTP::uri]
}
It looks like convert www.mysite.com to mysite.com, right? I need another way, right?
should be this way?
when HTTP_REQUEST {
if { [string tolower [HTTP::host]] equals "mysite.com" } {
HTTP::respond 301 Location http://www.mysite.com[HTTP::uri]
}
thanks,
Xin - Xin_99652
Nimbostratus
Hi there,
Actually, mycompany.com and www.mycompany.com are different site header, same IP for the same site (same pool in F5). Currently users can access the site by both URLs, but we are asked convert all mycompany.com to www.mycompany.com. So we need modify mycompany.com to www.mycompany.com.
I don't think my iRules are correct, could you help me?
thanks
when HTTP_REQUEST {
switch [HTTP::host] {
www.mycompany.com { pool pl_www_mycompany_com }
mycompany.com { HTTP::redirect "http://www.mycompany.com[HTTP::uri]"
pool pl_www_mycompany_com }
default { reject }
}
} - If you set the default pool on your virtual server to "pl_www_mycompany_com" then you will not have to specify it in the iRule. That is the preferred method unless there is some reason why you have another default pool setup.
Also, after a HTTP::redirect, you don't assign a pool as the redirect sends the 301 HTTP response right back to the client.
This should work for you:when HTTP_REQUEST { switch [string tolower [HTTP::host]] { "www.mycompany.com" { } "mycompany.com" { HTTP::redirect "http://www.mycompany.com[HTTP::uri]" } default { reject } } }
I threw in a "string tolower" since hostnames are case insensitive in most cases and your code would reject a request to "www.MyCompany.Com"
And feel free to thrown in the pool statement to the first "www.mycompany.com" case in case it isn't the default pool for your virtual server.
-Joe
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
