Forum Discussion
check for trailing slash in /foo and /foo/bar
Hi,
I have a case where I want to add a trailing slash if someone hit /foo or /foo/bar. The rules below works but I wonder if it can be optimized:
when HTTP_REQUEST {
add trailing slash for /foo
if {[string first "/" [HTTP::uri] 1] equals "-1" } {
HTTP::redirect "${protocol}://[HTTP::host][HTTP::uri]/"
}
add trailing slash for /foo/bar
if {[string first "/" [string range [HTTP::uri] [string first "/" [HTTP::uri] 1] end] 1] equals "-1"} {
HTTP::redirect "${protocol}://[HTTP::host][HTTP::uri]/"
}
add trailing slash for /foo and /foo/bar
if {([string first "/" [HTTP::uri] 1] equals "-1") or ([string first "/" [string range [HTTP::uri] [string first "/" [HTTP::uri] 1] end] 1] equals "-1")} {
HTTP::redirect "${protocol}://[HTTP::host][HTTP::uri]/"
}
}
Any ideas?
- Former Member
One thing which just came to my mind is that I need to exclude dot, for example index.html:
if {!([HTTP::uri] contains ".")} { if {([string first "/" [HTTP::uri] 1] equals "-1") or ([string first "/" [string range [HTTP::uri] [string first "/" [HTTP::uri] 1] end] 1] equals "-1")} { HTTP::redirect "${protocol}://[HTTP::host][HTTP::uri]/" } }
Which actually adds even one more check. My concern is if it will slow down the response (even a ms) from the balancer when doing a lot of sub checks.
- Brad_ParkerCirrus
This is a simple way of doing what you want:
when HTTP_REQUEST { if {not ([HTTP::path] ends_with "/")}{ HTTP::respond 301 noserver Location "${protocol}:://[HTTP::host][HTTP::path]" } }
One thing to mention though your original iRule used HTTP::uri, that will contain query parameters if they exist which would make your redirect look like this, http://some.domain.com/originalUri?parameter1=xyz/.
If you want to account for query parameters you could do this:
when HTTP_REQUEST { if {not ([HTTP::path] ends_with "/")}{ if {[HTTP::query] ne ""}{ set myuri "[HTTP::path]/?[HTTP::query]" } else { set myuri "[HTTP::path]/" } HTTP::respond 301 noserver Location "${protocol}:://[HTTP::host]$myuri" } }
- Brad_ParkerCirrusAs Kai mentions below, you will need additional logic to account for files that wouldn't want trailing slashes.
Hi Vova V,
I'm using [URI::basename] command to parse the last element of a given HTTP path. But keep in mind that some WebServices (e.g. ".asmx/method" ".json/method) don't like trailing slashes. So you may want to setup some exclusions...
This is the code I'm using for some SharePoint Sites...
when HTTP_REQUEST { if { [set uri_base [URI::basename [HTTP::path]]] eq "" } then { if { $debug } { log -noname local0. "The URI::basename is a /Folder/." } } elseif { $uri_base contains "." } then { if { $debug } { log -noname local0. "The URI::basename is a *.* File." } } else { if { $debug } { log -noname local0. "The URI::basename is a /Folder (without trailing slash)." } switch -glob -- [string tolower [HTTP::path]] "*.asmx*" - "*.json*" - "/_*" - "*/_layout*" - "*/_vti_bin*" { if { $debug } { log -noname local0. "The HTTP::path is exempted..." } } default { if { $debug } { log -noname local0. "Adding a trailing slash to the URI::basename." } HTTP::path "[HTTP::path]/" } } }
Cheers, Kai
Recent Discussions
Related Content
* 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