Forum Discussion
Fotios_30046
Nimbostratus
Sep 14, 2007Static URI Rewrites
Our website search functionality has gone through some heavy modifications recently and in doing so, the url's have been completely rewritten.
To give you a better understanding of whats going on, I'll list the old way and the new way.
www.site.com/common/search/searchcombined.asp?category=XXYYZZ
www.site.com/common/search/searchresult.aspx?categoryid=AABBCC
Additionally, we have a static list of mappings between XXYYZZ and AABBCC that I can populate into a list.
I've gone through the boards and put together the following iRule, but its not working.
class CategoryID
{
"LIGHTING 26"
"BEDROOM 30"
}
when HTTP_REQUEST
{
if {[HTTP::path] == "/searchcombined.asp" }
{
set qstring [HTTP::query]
set CategoryID1 [findstr "category=" [HTTP::query] 7 "&"]
if {$CategoryID1 != ""}
{
set CategoryID2 [findclass $CategoryID1 $::CategoryIDs " "]
if {$CategoryID2 != ""}
{
set qstring [string map [list $CategoryID1 $CategoryID2] $qstring]
}
}
HTTP::respond 301 Location "http://[HTTP::host]/common/search/SearchResult.aspx$qstring"
}
}Any help or suggestions would be great.
11 Replies
- You were really really close. There are a couple of issues with your iRule...Findstr usage
The usage of findstr is this:findstr
You are using it like this:findstr
Switch the two paramters around and you are half way there.
The next problem is with the skip count parameter. You are putting in 7, but "category=" is 9 so after you switch the paramters, your extracted string will be "y=XXYYZZ" when you really want it to be "XXYYZZ". Change the skip count to 9 and you should be all set.
I tested this iRule and it seems to work in my setup.
Data Group Namingwhen HTTP_REQUEST { if {[HTTP::path] == "/searchcombined.asp" } { set CategoryID1 [findstr [HTTP::query] "category=" 9 "&"] if {$CategoryID1 != ""} { set CategoryID2 [findclass $CategoryID1 $::CategoryIDs " "] if {$CategoryID2 != ""} { set qstring [string map [list $CategoryID1 $CategoryID2] $qstring] } } HTTP::respond 301 Location "http://[HTTP::host]/common/search/SearchResult.aspx?$qstring" } }
With that being said, I had to rename my data group to "CategoryIDs". In your post you named your data group "CategoryID". I assume this is just a typo but if not, you'll need to either rename your data group or change the value in the findclass command.301 redirect
You'll need to put a "?" between your new URI and the $qstring variable.One more thing...
Actually, possibly one more issue would be with the fact that you are issuing the HTTP::respond regardless of whether CategoryID1 is extracted from the URI or CategoryID2 is pulled from the data group. Maybe this is your intention, but thought I'd point it out. You could end up with redirects going to the SearchResult.aspx page with the original [HTTP::query] value.
In the future, I'd recommend throwing in a bunch of logging after every line where you assign or lookup values. That way by looking in the /var/log/ltm file it's fairly easy to diagnose where the logic breaks in your iRules. Then when things are working, comment it out for production use.
Hope this helps...
-Joe - Fotios_30046
Nimbostratus
Joe,
Thanks for the updated information. You were correct on the typo, I missed the s in my data group and that has been fixed. However, I don't see the rule working correctly in my environment.
I added logging under each set command to echo out the values, but nothing is showing up in the /var/log/ltm file other than my configuration changes. I know I actived this iRule on the VIP. Something else I might be missing?
log local0. "set command yeilds >$CategoryID1<" - If you are using log statements and they are not showing up in your /var/log/ltm file, then something is wrong with your configuration. Try putting this in your iRule
... when HTTP_REQUEST { log local0. "HTTP Request for URI: [HTTP::uri]" ... }
For every request you should see this line in the log file. Make sure also that you put the "local0." part in the log statement or the log messages can be batched up and not stored directly (maybe that's your issue).
If you issue a HTTP request through your virtual and you do not see the "HTTP Request for URI:..." in your logs, then you either don't have a HTTP profile associated with your virtual or the iRule is not set as a resource for that virtual. If both of those are true, then I'm somewhat baffled. Let me know how this progresses.
-Joe - Fotios_30046
Nimbostratus
Joe,
I don't see anything wrong with my particular configuration.when HTTP_REQUEST { if {[HTTP::path] == "/SearchCombined.asp"} { set CategoryID1 [findstr [HTTP::query] "category=" 9 "&"] log local0. "set command = >$CategoryID1<" if {$CategoryID1 != ""} { set CategoryID2 [findclass $CategoryID1 $::CategoryIDs " "] log local0. "set command = >$CategoryID2<" if {$CategoryID2 != ""} { set qstring [string map [list $CategoryID1 $CategoryID2] $qstring] log local0. "set command = >$qstring<" } } HTTP::respond 301 Location "http://[HTTP::host]/common/search/SearchResult.asp?$qstring" HTTP::respond 301 Location "http://[HTTP::host]/" } } - Fotios_30046
Nimbostratus
Gents,
I finally got it to work correctly. Here's the final rule setup.when HTTP_REQUEST { if {[HTTP::path] == "/common/search/SearchCombined.asp"} { set CategoryID1 [findstr [HTTP::query] "category=" 9 "&"] if {$CategoryID1 != ""} { set CategoryID2 [findclass $CategoryID1 $::CategoryIDs " "] } if {$CategoryID2 != ""} { HTTP::respond 301 Location "http://[HTTP::host]/common/search/SearchResult.asp?CategoryID=$CategoryID2" } } }
Thanks Again... - Great, glad to help... Feel free to post again if any other issues come up.
-Joe - In looking at your code, I see a couple possible of issues that may come up. Mainly with your "if {$CategorID2 != ""}" line. You only set that variable if the CategoryID1 value is found in the query string. What happens if it's not there? CategoryID2 will not get set and you will have a runtime error when trying to evaluate the value against the empty string. Also, if the user is on a keepalive connection, the variables you are setting are session variables so they will be around for the entire session and CategoryID2 could be set from a previous request and CategoryID1 isn't set from the current request.
I'd suggest nesting the CategoryID2 comparison in the previous if to avoid these possible issues.when HTTP_REQUEST { if {[HTTP::path] == "/common/search/SearchCombined.asp"} { set CategoryID1 [findstr [HTTP::query] "category=" 9 "&"] if {$CategoryID1 != ""} { set CategoryID2 [findclass $CategoryID1 $::CategoryIDs " "] if {$CategoryID2 != ""} { HTTP::respond 301 Location "http://[HTTP::host]/common/search/SearchResult.asp?CategoryID=$CategoryID2" } } } }
Make sense?
-Joe - Fotios_30046
Nimbostratus
Joe,
You're right, the nesting does make more sense.
Thanks Again,
Fotios - Great, glad to help... Please let us know if you have any other issues in the future as we'd be glad to do our best to help you out.
-Joe - Fotios_30046
Nimbostratus
During the iRule creation, a specific match list was given to me by our product management team. This list was very simple, that it had single text on one side and numerical matches on the left. Since I'm logging all variables within the iRule, I noticed that special characters are also possible as variables.
For instance, kids%20bedroom or accent+tables. Is there a way, I can strip out these special characters so that kids%20bedroom turns into kidsbedroom?
I tried playing around with setting the left part to one string and the right part to another and then joining them, but its not coming together correctly for me.
Any suggestions?
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