Forum Discussion
pt_73812
Nimbostratus
Jan 26, 2010dash in URI breaking pool selection?
Hello all,
I've run into a problem with an irule I'm working on. Basically, if there is a dash in the uri, the rule does not seem to pick it up correctly unless there's a trailing slash at the end of the uri. This is a snippet of the code I'm working with:
when HTTP_REQUEST {
if { [HTTP::path] equals "/" } {
pool unix_servers
} elseif { [string tolower [HTTP::uri]] starts_with "/tv/my-link" } {
pool windows_servers
} elseif { [string tolower [HTTP::uri]] starts_with "/tv" } {
pool unix_servers
} else {
pool windows_servers
}
}
Now, if I go to http://www.xyz.com/tv/my-link in my browser, not only am I not being sent to the windows pool, but the url that shows up in the browser is http://www.xyz.com/tv
If I go to http://www.xyz.com/tv/my-link/ I get sent to the correct windows pool and get the correct content.
Can I not have a dash in the uri? Or is something else causing the problem?
12 Replies
- hoolio
Cirrostratus
I don't think a hyphen in the comparison strings would cause a problem with an iRule. And I don't think LTM would truncate the requested URI/path unless you explicitly modify the URI/path.
/tv/my-link should match the second if condition and go to the windows_servers pool. If you add logging to the iRule, can you check which pool is being matched for requests to /tv/my-link?
Thanks,
Aaron - hoolio
Cirrostratus
Sorry, I should have clarified. Here is a version which logs the URI checks and pool selection. Can you post the anonymized log output from /var/log/ltm for a failure?when HTTP_REQUEST { log local0. "[IP::client_addr]:[TCP::client_port]: [HTTP::method] request to [HTTP::host][HTTP::uri]" if { [HTTP::path] equals "/" } { log local0. "[IP::client_addr]:[TCP::client_port]: Matched /, using unix_servers" pool unix_servers } elseif { [string tolower [HTTP::uri]] starts_with "/tv/my-link/" } { log local0. "[IP::client_addr]:[TCP::client_port]: Matched /tv/my-link, using windows_servers" pool windows_servers } elseif { [string tolower [HTTP::uri]] starts_with "/whatever" } { log local0. "[IP::client_addr]:[TCP::client_port]: Matched /whatever, using unix_servers" pool unix_servers } else { log local0. "[IP::client_addr]:[TCP::client_port]: No match, using windows_servers" pool windows_servers } } when SERVER_CONNECTED { log local0. "[IP::client_addr]:[TCP::client_port]: Server info: [LB::server]" }
Thanks,
Aaron - hoolio
Cirrostratus
Is the edited version of the rule in your first post what you're testing with now? If so, a request for /tv/my-list won't match the first check for /tv/my-link, but will match the second check for /tv. A request for /tv/my-link will match the first check for /tv/my-link. In an if/elseif/.../else chain, only the first matching condition's action will be taken.
If the rule you're testing is different than your first post, can you post the current version? Can you also clarify which requested URI is failing to match the correct condition and/or which requested URI is going to the wrong pool? If it's a pool selection issue, it would help to include the SERVER_CONNECTED event and the debug log statement there.
Thanks,
Aaron - pt_73812
Nimbostratus
*sigh* let me apologize again. In my haste to get this solved, I'm being careless with my typing. There is no "my-list" anywhere - that was me fat fingering "my-link".
The code in my first post is the what I'm testing against. - pt_73812
Nimbostratus
With server connected output:
Jan 26 11:55:11 tmm tmm[1643]: Rule log_test : 71.x.x.x:1438: GET request to www.xyz.com/tv/my-link
Jan 26 11:55:11 tmm tmm[1643]: Rule log_test : 71.x.x.x:1438: Matched /tv, using unix_servers
Jan 26 11:55:11 tmm tmm[1643]: Rule log_test : 71.x.x.x:1438: Server info: unixprod 10.xx.xx.95 80
Jan 26 11:55:11 tmm tmm[1643]: Rule log_test : 71.x.x.x:1438: GET request to www.xyz.com/tv
Jan 26 11:55:11 tmm tmm[1643]: Rule log_test : 71.x.x.x:1438: Matched /tv, using unix_servers
Jan 26 11:55:11 tmm tmm[1643]: Rule log_test : 71.x.x.x:1438: Server info: unixprod 10.xx.xx.96 80 - pt_73812
Nimbostratus
And just to add to the confusion, if I change the code to thiswhen HTTP_REQUEST { if { [HTTP::path] equals "/" } { pool unix_servers } elseif { [string tolower [HTTP::uri]] starts_with "/tv/my" } { pool windows_servers } elseif { [string tolower [HTTP::uri]] starts_with "/tv" } { pool unix_servers } else { pool windows_servers } }
Jan 26 12:00:29 tmm tmm[1643]: Rule log_test : 71.x.x.x:1462: GET request to www.xyz.com/tv/my-link
Jan 26 12:00:29 tmm tmm[1643]: Rule log_test : 71.x.x.x:1462: Matched /tv/my-link, using windows_servers
Jan 26 12:00:29 tmm tmm[1643]: Rule log_test : 71.x.x.x:1462: Server info: win_servers 10.x.x.5 80 - hoolio
Cirrostratus
Aye... so you're saying that the logs lines are actually this:
Jan 26 11:23:52 tmm tmm[1643]: Rule log_test : 71.x.x.x:1370: GET request to www.xyz.com/tv/my-link
Jan 26 11:23:52 tmm tmm[1643]: Rule log_test : 71.x.x.x:1370: Matched /tv, using unix_servers
Jan 26 11:23:52 tmm tmm[1643]: Rule log_test : 71.x.x.x:1371: GET request to www.xyz.com/tv
Jan 26 11:23:52 tmm tmm[1643]: Rule log_test : 71.x.x.x:1371: Matched /tv, using unix_servers
Jan 26 11:37:05 tmm tmm[1643]: Rule log_test : 71.x.x.x:1387: GET request to www.xyz.com/tv/my-link/
Jan 26 11:37:05 tmm tmm[1643]: Rule log_test : 71.x.x.x:1387: Matched /tv/my-link, using windows_servers
So a request to /tv/my-link doesn't match the same condition as a request for /tv/my-link/ when you're checking for '[HTTP::uri] starts_with "/tv/my-link"'? If so, that's quite odd. The string matching should be fairly bullet proof. I can't see how this could be happening if the anonymized strings you're posting accurately reflect the iRule you're testing.
Here is a simple test iRule which shows the matching working:when RULE_INIT { set my_uri "/tv" log local0. "uri: $my_uri" if {$my_uri starts_with "/tv/my-link"}{ log local0. "matched /tv/my-link" } elseif {$my_uri starts_with "/tv"}{ log local0. "matched /tv" } else { log local0. "no match" } }
And log output for a few sample $my_uri values:
: uri: /tv/my-link/test123
: matched /tv/my-link
: uri: /tv/my-link
: matched /tv/my-link
: uri: /tv/
: matched /tv
: uri: /tv
: matched /tv
Aaron - pt_73812
Nimbostratus
Follow up question. Could OneConnect Transformations being enabled cause any of the problems I'm seeing? I turned off the OneConnect profile I had on the virtual server, but noticed that OneConnect Transformations are enabled in the http profile. - pt_73812
Nimbostratus
After playing around with this some more and adjusting some of the logging I started to notice the there was a second GET request. The second request was changing the dash from the original uri to %2d. This in turn was messing up the uri starts_with. I tried adding a check for %2d, but, more than likely was doing something wrong as it still wouldn't send the request to correct pool. Since I was in a bit of a time crunch, I eventually Swallowed my pride and called F5 support and the gentleman who was helping had me do some specific tcp dumps where he noticed that the second request was in fact an IIS 6.0 generated 301 redirect that was appending a / to the end of the uri, but was also at the same time changing the - to a %2d. Got my windows admin on the line and he was able to come up with an asapi re-write to do a cleaner redirect, which maintained the -. Once that was done, the irules worked perfectly.
Aaron - thank you for the help. The logging got me headed in the right direction to notice the %2d - Hamish
Cirrocumulus
Perhaps another answer would be to always decode URI's before checking them against fixed strings, where encodable characters are in the fixed string?
e.g. (Quick hack, you can do better)when HTTP_REQUEST { if { [HTTP::path] equals "/" } { pool unix_servers } elseif { [string tolower [decode_uri [HTTP::uri]]] starts_with "/tv/my-link" } { pool windows_servers } elseif { [string tolower [decode_uri[HTTP::uri]]] starts_with "/tv" } { pool unix_servers } else { pool windows_servers } }
Edit:
Note that decode_uri is a v4 function. v9 and above should use URI::decode
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
