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=exa...
Andy_Herrman_22
Nimbostratus
Sep 28, 2007So, 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:
http://yourhost/path/with/zone/in/it?foo=bar
http://yourhost/path/with/zone/in/it?zoneId=1234
http://yourhost/thingy?amICrazy=probably
http://yourhost/thingy?zoneId=6543
All of those URLs will hit the "else" case and go to the default pool. No zoneId verification will happen. Maybe that's what you want, but from your description earlier it didn't sound like it was, so I wanted to make sure you realized it had this behavior.
As for the second thing, making sure you only get the "zoneId" parameter and not something like "myDummyzoneId", you'd have to include the character that appears before "zoneId". There are two possibilities here. Either the query string starts with "zoneId" (first parameter), in which case there is no starting parameter. To detect this you'd use starts_with on the query string. The other possibility is that zoneId is preceeded by a "&" (second or later query parameter). For this you'd use findstr and search for "&zoneId=".
Here's the code I threw together earlier, but I'll give a bit more explanation this time.
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
}
}
----------------------
At the very beginning we check to see if "/zone/" is in the path. If it is then we start checking for zoneId in the query params. If it isn't then we set the pool. Note that this check will only work if "zone" isn't the last part of the path. It's possible you could get a URL like "http://path/containing/zone" which has "zone" in it but doesn't have "/zone/" because the last "/" isn't always included.
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
}
We start the zoneId check by extracting zoneId. First we check to see if the query string starts with "zoneId". If it does then we use findstr to pull it out. Calling findstr with just "zoneId=" as its argument works here because we know the first instance of "zoneId=" it finds in the query string will be the one we want.
If it doesn't start with zoneId then search for "&zoneId=". Having the "&" at the beginning makes sure that we don't accidentally grab the value for something that simply ends in "zoneId" like "myDummyzoneId".
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 "&"]
}
Next we check to make sure the zoneId was actually defined in the query params. I don't know what you'd want to do in this case, but maybe define a default zoneId or reject the connection.
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 we do have a zoneId then we check to see if there were any other query parameters. If there were we redirect. Otherwise we do whatever you want to do when the URL is valid.
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
}
Hopefully that made sense and didn't just completely confuse you.
-Andy
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