Forum Discussion
Regex
http://subdomain.ourcompany.com/webext/01.aspx?status=error (pass the 01 over to the url below and say id=thatNumber)
needs to rewrite to
http://subdomain.ourcompany.com/post/post.ashx?id=01&status=error
I'm trying to make sure I'm going in the right direction here by using regex to analyze the URI, however the 01.aspx will be a different number, it will not always come from the application that way.
The web application may spit out a different error number such as 45.aspx or 123.aspx. The web application increments this number based on the number of errors received within the application, so there's a possibility that we will get into triple, 4, 5, 6 digits in the future.
The only thing that changes in the uri is this number. The ?status=error needs to be appended and the number moved over to result in something like:
http://subdomain.ourcompany.com/post/post.ashx?id=01&status=error
I found this iRule - can I use this or something similar to increment using \d+ to say one or more digits within the regex?
Or a string match?
string match -nocase {[0-9999][[0-9999]}
Thanks for any help - I'm unsure how to move forward.
elseif {[HTTP::host] == "subdomain.ourcompany.com" } { if { [HTTP::uri] contains "/webext/\d+.aspx?status=error"} {
set urivar
if { ! ( $urivar matches_regex ^.*?
\/webext\/\d+\[a-zA-Z0-9]) } {
rewrite here
}
else {
pool something else
}
}
13 Replies
- Joe_Pipitone
Nimbostratus
OK, I've been able to string match somewhat using the following:
if { ([HTTP::host] eq "
subdomain.ourcompany.com") and ([string match {/webext/[0-999]*} [HTTP::uri]]) } {
However, the following does not match for some reason:
if { ([HTTP::host] eq "subdomain.ourcompany.com") and ([string match {/webext/[0-999].aspx?status=error} [HTTP::uri]]) } {
strange? - The reason the match doesn't work is that the sections between the brackets represents a single character. I'm not sure how the interpreter will deal with 999 in this case, but it's not the way you are thinking.
Let's step back a bit and rethink the problem. Whenever I hear "regex" I cringe because it's such a costly operation. In some cases, it's the only way to go, but for this case where you know the format of the inbound URI, it's fairly easy to use the TCL string functions to extract the value of ID. Something like this should work for youwhen HTTP_REQUEST { Lowercase the URI for string comparison purposes (.aspx implies case-insensitive URIs) set uri [string tolower [HTTP::uri]] Only process URIs of the format /webext/xxxxx.aspx?status=error if { ($uri starts_with "/webext/") && ($uri ends_with ".aspx?status=error") } { Set the start index to the first char after "/webext/" in the URI set idxStart 8 Set the end index to the dot in ".aspx". set idxEnd [string first ".aspx" $uri] if { -1 != $idxEnd } { decrement the end index to the last character in the id incr idxEnd -1; extract the id from the uri from the uri set id [string range $uri $idxStart $idxEnd] Issue the redirect HTTP::redirect "http://[HTTP::host]/post/post.ashx?id=${id}&status=error" } } }
Granted, I made some assumptions here that you won't be handling URI's with both numbers/characters between the "/webext/" and ".aspx?status=error". It should still work, but it will replace the value of the "id" variable with whatever is between those two strings.
Hope this helps...
-Joe - Joe_Pipitone
Nimbostratus
Wow - thank you Joe.One other question - I've been told that these numbers will increment fairly quickly (the app is very buggy) and they've requested that I up the number quite a bit.
Let's say I want to use a number such as [0-99999999] - would I simply change your code to reflect that many characters?
- Joe_Pipitone
Nimbostratus
Nevermind - I took another look at your code and saw it does exactly what I needed!
Only change I had to make was to change this:
Issue the redirect
HTTP::redirect "[HTTP::host]/post/post.ashx?id=${id}&status=error" / to this (it was appending the host name twice in the beginning of the url)
Issue the redirect
HTTP::redirect "/post/post.ashx?id=${id}&status=error" Your help is greatly appreciated. - No change is necessary. This will work for any length number. Since I'm using the "string first" to get the index of the ".aspx" that will increase the larger the id is.
For this:
http://server/webext/123.aspx?status=error
idxStart would be where the "1" is and idxEnd would be where the "3" is. The string range will then return "123"
For
http://server/webext/123456789.aspx?status=error
idxStart would be the "1" and idxEnd would be where the "9" is. The string range will then return "123456789"
Keep in mind that this does no validation that what's in the URI in that section is actually a number. For
http://server/webext/foo/bar/yahoo.aspx?status=error
The extracted ID would be "foo/bar/yahoo". But I'm assuming that you know the format of the application. You might want to thrown in a verification check in there.
-Joe - Oops, left out the beginning "http://" from the redirect command. Your way should work though if you are redirecting to the same hostname.
- Joe_Pipitone
Nimbostratus
Awesome - either way works. Tell me, how did you incorporate code tags to your post? every time I try using [code ] it doesn't display correctly, I've resorted to blockquote tags.
Using code tags only seems to work using quick reply.
Thanks again Joe - hoolio
Cirrostratus
Another option would be to extract the web object and extension using URI::basename:
http://devcentral.f5.com/wiki/default.aspx/iRules/URI__basename.htmlwhen HTTP_REQUEST { Check if URI starts with /webext and there is a query string parameter named status set to "error" if {[string tolower [HTTP::uri]] starts_with "/webext" and [URI::query "?&[HTTP::query] &status] eq "error"}{ Parse 000file.ext from /path/to/000file.ext and save the leading digits to the $id variable where 000 is one or more digits and file.ext is any string scan [URI::basename [HTTP::uri]] {%[0-9]%s} id rest if {$id ne ""}{ log local0. "Scanned $id from $uri" HTTP::redirect "http://[HTTP::host]/post/post.ashx?id=${id}&status=error" } } }
Aaron - Joe_Pipitone
Nimbostratus
Hey guys,Turns out that rather than capturing ?status=error and passing it along, this needs to take whatever is after .aspx and append it, no matter what it is.
For example, they want the following examples to be able to work:
from:
http://server/webex/(.*).aspx?(.*)
to:
http://server/post/post.ashx?id=$1&$2
more examples:
http://server/webex/10.aspx?status=Good -> http://server/post/post.ashx?id=10&status=good
http://server/webex/10.aspx -> http://server/post/post.ashx?id=10
http://server/webex/234234.aspx?* -> http://server/post/post.ashx?id=234234&*
Does this iRule need to be completely re-worked all over again?
I was thinking of doing something like this:
HTTP::redirect "/post/post.ashx?id=${id}&[HTTP::query]"
rather than
HTTP::redirect "/post/post.ashx?id=${id}&status=error"
Thanks for any help, I'm trying to work on it on my own as well.
- hoolio
Cirrostratus
Can you try this? You might get a trailing & in the query string if there wasn't a query string already. But hopefully that won't break anything.when HTTP_REQUEST { Check if URI starts with /webex/ if {[string tolower [HTTP::uri]] starts_with "/webex/"}{ Parse 000file.ext from /path/to/000file.ext and save the leading digits to the $id variable where 000 is one or more digits and file.ext is any string scan [URI::basename [HTTP::uri]] {%[0-9]%s} id rest if {$id ne ""}{ log local0. "Scanned $id from $uri" HTTP::redirect "http://[HTTP::host]/post/post.ashx?id=${id}&[HTTP::query]" } } }
Aaron
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)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