Forum Discussion

Troy_Atwood_942's avatar
Troy_Atwood_942
Icon for Nimbostratus rankNimbostratus
Mar 08, 2011

3 scenario 301 redirection problem

We are moving sections of our website to a new url structure and need to redirect only the sections that are moving.

 

 

Sounds like a job for IRules!

 

 

We have 3 scenarios that we need to intercept and 301 redirect.

 

 

First Scenario:

 

We have urls that have the following data in the url;

 

 

/docs/1201

 

/DOC-1201

 

 

The 1201 of course is the content identifier and we need to capture that data and pass it to this link. www..com/kredirect/doc/xxxx which will then 301 redirect to the new url. Is it possible to avoid a double redirect at the client?

 

 

Second Scenario:

 

 

This scenario does not require an extensive id look and only needs part of the url before the blog title replaced with the new location.

 

www..com/cm/comm/kn/blog/title-of-blog-post/?cs=xxxxx

 

301 to www..com/cm/blogs/newarea/title-of-blog-post/?cs=xxxxx

 

 

The last scenario:

 

 

We have several pages that will cease to exist and this rule needs to 301 redirect the urls to the same landing page.

 

www..com/cm/comm/kn?view=documents&numResults=25

 

www..com/cm/message/1406

 

www..com/cm/post!input.jspa?containerType=14&container=20130

 

www..com/cm/edit.jspa

 

www..com/cm/thread/

 

www..com/cm/comm/feeds/messages

 

www..com/cm/tags?containerType=44&container=2013

 

www..com/cm/pm-view.jspa?pmID=1022

 

www..com/cm/addressbook.jspa

 

 

301 to www..com/newlanding/

 

 

Can all of this be encapsulated in the same iRule?

 

 

Please point this iRule newbie in the right direction and any help would be greatly appreciated.

 

 

 

  • This should all be possible within the same iRule. I would take a look at some of the native URI parsing commands to start with and avoid regexes if at all possible.

     

     

    http://devcentral.f5.com/wiki/default.aspx/iRules/http__uri

     

    http://devcentral.f5.com/wiki/default.aspx/iRules/http__path

     

    http://devcentral.f5.com/wiki/default.aspx/iRules/uri

     

     

    Here is one example we discussed recently:

     

    http://devcentral.f5.com/Community/GroupDetails/tabid/1082223/asg/50/afv/topic/aft/1177132/aff/5/showtab/groupforums/Default.aspx

     

     

    If you have a lot of URIs to all redirect to the same page (or generally take the same action), you could add them to a string datagroup and then use the class (v10) or matchclass (v9) commands to check the requested URI against the list. If you're app is case-insensitive, set the URI and the strings in the datagroup to lower case using 'string tolower "string"' before doing the class lookup.

     

     

    http://devcentral.f5.com/wiki/default.aspx/iRules/class

     

    http://devcentral.f5.com/wiki/default.aspx/iRules/matchclass

     

     

    Keep in mind that the values for most HTTP:: commands are cached within the same event and event priority. So if you log the value, change it and then try to log it again, the logging won't show the change even though it's been made.

     

     

    If you get stuck, reply here with what you've tried and what's not working.

     

     

    Aaron
  • Here is my first iRule made possible via all of the great examples I found in the forum.

     

     

    when RULE_INIT {

     

    Debug off (0), Errors-only(1), On(2) or Verbose(3)

     

    set ::debug 0

     

    }

     

    when HTTP_REQUEST {

     

     

    set H [string tolower [HTTP::host]]

     

    set uri [string tolower [HTTP::uri]]

     

    set A [HTTP::host][HTTP::uri]

     

     

    only test urls that need to be redirected.

     

    if { [class match $uri contains jm_urls] } {

     

     

    print the incoming uri so we can compare before/after results in the ltm log:

     

    if { $::debug>=2 } { log local0. " iRule TEST input before we mess with it: $H$uri "}

     

     

    Case 1: if I can match a target uri, substitue the first part, plus everything after the

     

    old 22 character length target uri that I"m replacing.

     

    if { $uri contains "/bn/community/jm/blog/" } {

     

    set puri [substr $uri 22 ";"]

     

    HTTP::respond 301 Location "http://$H/bn/blogs/dl/$puri"

     

    if { $::debug>=2 } { log local0. " Test Case 1 satisfied "

     

    set A "http://$H/bn/blogs/dl/$puri"

     

    }

     

    Case 2: now lets chase down document numbers, and redirect if we find a target:

     

     

    } elseif { $uri contains "/bn/docs/doc-" } {

     

    set puri [substr $uri 13 ";"]

     

    HTTP::respond 301 Location "http://$H/jmredirect/doc/$puri"

     

    if { $::debug>=2 } { log local0. " Test Case 2.1 satisfied "

     

    set A "http://$H/jmredirect/doc/$puri"

     

    }

     

    } elseif { $uri contains "/bn/docs/" } {

     

    set puri [substr $uri 9 ";"]

     

    HTTP::respond 301 Location "http://$H/jmredirect/doc/$puri"

     

    if { $::debug>=2 } { log local0. " Test Case 2.2 satisfied "

     

    set A "http://$H/jmredirect/doc/$puri"

     

    }

     

    Case 3: lets redirect the door page. redirects. Third verse, same as the first...

     

     

    } elseif { $uri ends_with "/bn/community/jm/" } {

     

    HTTP::respond 301 Location "http://$H/dl/"

     

    if { $::debug>=2 } { log local0. " Test Case 3 satisfied "

     

    set A "http://$H/dl/"

     

    }

     

    Case 4: lets redirect everything else to the /dl/downloadinvalid.aspx page.

     

     

    } else {

     

    HTTP::respond 301 Location "http://$H/dl/downloadinvalid.aspx"

     

    if { $::debug>=2 } { log local0. " Test Case 4 satisfied "

     

    set A "http://$H/dl/downloadinvalid.aspx"

     

    }

     

    }

     

    show me what the rewritten uri looks like in the logs. log file should have three lines of

     

    code-generated log messages each time this iRule fires:

     

     

    " iRule TEST input before we mess with it: "

     

    " Test Case satisfied "

     

    " iRule TEST output: "

     

     

     

    if { $::debug>=2 } {log local0. " iRule TEST output: $A " }

     

     

    }

     

    }

     

     

    Any feedback would be welcome.

     

     

    Thanks,

     

     

    Troy
  • Hi Troy,

     

     

    That looks good. Does the rule work for your requirements?

     

     

    As you're comparing the same thing in all of the if/elseif/.../else statements, you could replace them with a switch statement. But that's really a matter of preference.

     

     

    Aaron
  • It is working well in the QA environment so we will see how the PROD rollout goes....;-) When I added the 4th case I thought about using a switch statement instead. Since I am ahead of the web developers I will probably give that a try since we will be moving more areas in the near future.

     

     

    I do have a concern with Case 2, I am passing the parameter to a web page that will do the look up and send a redirect to the actual page. Is there a way that I could issue the http request to the redirect page and then return the actual 301 url redirect to the client to avoid a double 301 redirect?

     

     

    The links you sent were very helpful.

     

     

    Thanks,

     

     

    Troy

     

  • Colin_Walker_12's avatar
    Colin_Walker_12
    Historic F5 Account
    Switch is definitely more efficient. It's also, in my opinion, far more readable. We tend to encourage folks to go that route if they're comfortable with it. ;)

     

     

    Looks good so far, let us know if there are any questions/issues.

     

     

    Colin