Forum Discussion
Dayton_Gray_103
Nimbostratus
Sep 20, 2007Change URI parameters with a 301 redirect
I am looking to change a URI to remove certain query string parameters and redirect with a 301.
Example:
Incoming URI
www.example.com/example.jsp?zoneId=624906&zz=2255956&parentPage=example
or
www.example.com/example.jsp?zz=2255956&zoneId=624906&parentPage=example
to:
www.example.com/example.jsp?zoneId=624906
Basically I want to capture the zoneId parameter and drop everything else. The zoneId parameter could exist anywhere in the string.
Any help would be appreciated!
- iRules has a helper function that will do exactly what you want. The findstr command searches a string for a substring and returns that substring up to a terminating character.
when HTTP_REQUEST { set zoneid [findstr [HTTP::uri] "zoneId=" 0 "&"] if { [string length $zoneid] > 0 } { HTTP::redirect "http://[HTTP::host][HTTP::path]?$zoneid" } }
- Dayton_Gray_103
Nimbostratus
Joe, - Dayton_Gray_103
Nimbostratus
*bump* Anyone? - The problem is that you are inserting a header in the HTTP response but that is not sent back as part of the request. If you would like to send the client something in the response and have it persisted and sent back on subsequent requests, you'll have to use a HTTP Cookie. The problem with the Cookie approach is that it will be present at a minimum of the current connection. Then future requests within the same connection will still think they have been redirected, when they actually weren't.
when HTTP_REQUEST { if { ! ([HTTP::uri] contains "zoneId=") } { if { [HTTP::path] contains "/zone/" } { set zoneid [findstr [HTTP::uri] "zoneId=" 0 "&"] if { [string length $zoneid] > 0 } { HTTP::respond 301 Location "http://[HTTP::host][HTTP::path]?$zoneid" } } } }
- Andy_Herrman_22
Nimbostratus
Are you always removing everything but the zoneID, or is it possible that you'll get a URL with other parameters that you'll want to keep?when HTTP_REQUEST { set zoneID "" if { [HTTP::query] starts_with "zoneID=" } { We know the first entry is the correct one, so we don't need to worry about other params that end in "zoneID" set zoneID [findstr [HTTP::query] "zoneID=" 7 "&"] } else { set zoneID [findstr [HTTP::query] "&zoneID=" 8 "&"] } if { $zoneID == "" } { log local0. "No zoneID defined!" } if { [HTTP::query] contains "&" } { log local0. "Multiple parameters, need to redirect" Do your redirect here } else { log local0. "Only zoneID provided, no redirect" Do whatever you want to do when not redirecting } }
- Dayton_Gray_103
Nimbostratus
Joe, - Dayton_Gray_103
Nimbostratus
The final iRule that seems to be working well is:when HTTP_REQUEST { if { [HTTP::query] contains "&" } { if { [HTTP::path] contains "/zone/" } { set zoneid [findstr [HTTP::uri] "zoneId=" 0 "&"] if { [string length $zoneid] > 0 } { HTTP::respond 301 Location "http://[HTTP::host][HTTP::path]?$zoneid" } } } else { pool misc_pool } }
- Andy_Herrman_22
Nimbostratus
What happens if the URL only has a single query parameter and it isn't zoneID? Right now your irule will treat it exactly the same as a URL that only has the zone ID. - Dayton_Gray_103
Nimbostratus
aherrman,set zoneid [findstr [HTTP::uri] starts_with "zoneId=" 0 "&"]
- Andy_Herrman_22
Nimbostratus
So, it's possible that what happens with only a single query parameter is exactly what you want, I just wanted to make sure. It sounds like you always want to make sure there is just a single query parameter, and that it's "zoneID". Right now your irule will treat the following URLs the same:when HTTP_REQUEST { set zoneId "" if { [HTTP::path] contains "/zone/" } { if { [HTTP::query] starts_with "zoneId=" } { We know the first entry is the correct one, so we don't need to worry about other params that end in "zoneId" set zoneId [findstr [HTTP::query] "zoneId=" 7 "&"] } else { set zoneId [findstr [HTTP::query] "&zoneId=" 8 "&"] } if { $zoneId == "" } { log local0. "No zoneId defined!" set zoneId to some default zoneId, or reject the connection if that's what you want to do here } else { if { [HTTP::query] contains "&" } { log local0. "Multiple parameters, need to redirect" HTTP::respond 301 Location "http://[HTTP::host][HTTP::path]?$zoneId" } else { log local0. "Only zoneId provided, no redirect" Do whatever you want to do when not redirecting } } } else { Do whatever you want to do when /zone/ isn't in the path pool misc_pool } }
if { [HTTP::path] contains "/zone/" } { do zoneId check here. This is gone over below } else { Do whatever you want to do when /zone/ isn't in the path pool misc_pool }
set zoneId "" if { [HTTP::query] starts_with "zoneId=" } { We know the first entry is the correct one, so we don't need to worry about other params that end in "zoneId" set zoneId [findstr [HTTP::query] "zoneId=" 7 "&"] } else { set zoneId [findstr [HTTP::query] "&zoneId=" 8 "&"] }
if { $zoneId == "" } { log local0. "No zoneId defined!" set zoneId to some default zoneId, or reject the connection if that's what you want to do here }
if { [HTTP::query] contains "&" } { log local0. "Multiple parameters, need to redirect" HTTP::respond 301 Location "http://[HTTP::host][HTTP::path]?$zoneId" } else { log local0. "Only zoneId provided, no redirect" Do whatever you want to do when not redirecting }
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