Forum Discussion
C_D_18583
Nimbostratus
Nov 03, 2005String Manipulation
I have the following piece of code in my iRule
elseif { $uri starts_with "/nexus/" } {
pool pool1 }
elseif { $uri starts_with "/earth/" } {
pool pool2}
elseif { [string index [HTTP::uri] end] ne "/" } {
HTTP::redirect "http://[HTTP::host][HTTP::uri]/"
}
else {
pool pool3
}
}
The string extract is added just incase the user forgets to adds a / after the servlet context. The problem I have with this is that when the following request is received
http://testdomain.com/add.html
What happens is a / is appended as http://testdomain.com/add.html/ and then redirected to pool 3 which causes a 404.
1) How do I rewrite the rule so that when http://testdomain.com/add.html is received I can by pass the string/redirect statement?
2) If the servlet context does not match any above, the request should be directed to pool3 ?
6 Replies
- You could do a "ends_with" comparison before your check for the slash. if you know the valid extensions that you don't want appended with slashes this should work.
While you are at it you could use the ends_with in place of your string index command as well.elseif { $uri starts_with "/nexus/" } { pool pool1 } elseif { $uri starts_with "/earth/" } { pool pool2 } elseif { [HTTP::uri] ends_with ".html" } { pool pool3 } elseif { not ([HTTP::uri] ends_with "/") } { HTTP::redirect "http://[HTTP::host][HTTP::uri]/" } else { pool pool3 }
Is this what you are going for? If not, if you could provide a clear set of inputs and expected results, it will be easier for us to figure out a solution.
-Joe - unRuleY_95363Historic F5 AccountA more generic approach may be to simply check the basename for a period and only add the slash if one was not found and it doesn't end with one:
... if { not ([URI::basename $uri] contains ".") and not ($uri ends_with "/") } { HTTP::redirect "http://[HTTP::host][HTTP::uri]/" } ... - C_D_18583
Nimbostratus
...if { not ([URI::basename $uri] contains ".") and not ($uri ends_with "/") } { HTTP::redirect "http://[HTTP::host][HTTP::uri]/"} ...
Thanks , the above statement is very close
The basename is picking the last item of the uri after the last /
For example If I have this case.
http://testdomain.com/ADforms/trial
Basename picks up trial . I need to extract the first value after the domain which is ADforms . If it does not contain a "." or it does not end with a / then do the HTTP redirect, else go to the next statement. - getfield should get you where you want to go. You can use getfield to extract a specified field from a string. Using a slash as a delimiter and selecting field 2 you can get the first value after the slash in the URI.
This will get you the token without the slashes. You can check for the existence of a "." at that point but you won't be able to see if it ended with a slash. I'd suggest for that check you rescan the URI for the extracted token with a slash appended to it.
So, something like this should work:Extract first element after slash in URI set f [getfield [HTTP::uri] "/" 2] Check if field contains doesn't contain a dot and if the uri doesn't contain the field followed by a slash if { not ($f contains ".") and not ([HTTP::uri] contains "${f}/") } { Perform redirect. HTTP::redirect "http://[HTTP::host]/${f}/" }
You could possibly use HTTP::uri in the redirect with a slash appended. That should produce the same result.
*Standard disclaimer: this iRule hasn't been tested...
-Joe - C_D_18583
Nimbostratus
Thanks Joe, I will try this - unRuleY_95363Historic F5 AccountI don't know if any of this will help, but...
BTW, we also have a command: URI::path
This command has the following forms:
URI::path - returns the complete path excluding the basename.
URI::path - return the portion of the path starting after .
URI::path - return the portion of the path specified.
URI::path depth - return the number of directory levels in the path.
I'd also like to highlight another command that doesn't seem to get much airtime:
URI::compare
This command compares two uris without regard to case or encoding.
Unfortunately it doesn't yet support starts_with, ends_with or contains.
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
