Forum Discussion

Brandon_11574's avatar
Brandon_11574
Icon for Nimbostratus rankNimbostratus
Mar 24, 2011

Rewrite Rule

I am needing to do a URL Rewrite where a visitor requests http://domain.com/newFolder/ but they actually see the content from http://domain.com/oldFolder/

 

 

So when they request http://domain.com/newFolder/page1.html the address bar of their browser doesn't change, but they actually see the contents of http://domain.com/oldFolder/page1.html.

 

 

I need the rule to be able to do this for any page or image on the site, like the following examples:

 

 

http://domain.com/newFolder/page2.html <- http://domain.com/oldFolder/page2.html

 

http://domain.com/newFolder/image1.gif <- http://domain.com/oldFolder/image1.gif

 

http://domain.com/newFolder/about/index.html <- http://domain.com/oldFolder/about/index.html

 

http://domain.com/newFolder/images/image2.gif <- http://domain.com/oldFolder/images/image2.gif

 

 

How do you go about doing this in iRules? Any documentation on this specific type of iRule?

 

 

Thanks in advance,

 

 

Brandon Petersen

 

  • Hi Brandon,

     

     

    You can use Kirk's ProxyPass iRule for this:

     

     

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

     

    http://devcentral.f5.com/wiki/default.aspx/iRules/proxypass (v9)

     

     

    Aaron
  • Here is another option that is a little lighter:

    This should change the path on the request going to the server and mask it in the client browser.

    
    when HTTP_REQUEST {
    switch -glob [ string tolower [HTTP::uri] ] {
    "/oldFolder/*" { HTTP::uri [ string map {"oldFolder" "newFolder"} [HTTP::uri] ] }
    }
    }
    

    Let me know if you have any problems wth it.
  • If the app responds with /oldFolder/ in the path, you'd also want to rewrite it to /newFolder/ in redirects and response content. You can do this using using HTTP::is_redirect and a stream profile and STREAM::expression.

     

     

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

     

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

     

     

    Aaron
  • Thanks Michael,

     

     

    That code worked the way I needed. It is now rewriting the pages. I did notice one issue. We're using SharePoint and it doesn't seem to handle 302 redirectsl. For example, when you go to the page http://domain.com/oldFolder/ the SharePoint server wants to 302 redirect to http://domain.com/oldFolder/pages/default.aspx. It doesn't seem to like that transition.

     

     

    Otherwise it is displaying pages and images correctly as long as there isn't a 302 redirect being performed by the SharePoint Server.
  • Now I'm onto replacing all instances of /oldFolder/ with /newFolder/ in the page content, does this look right?

     

     

    when HTTP_REQUEST {

     

    switch -glob [ string tolower [HTTP::uri] ] {

     

    "/newFolder/*" {

     

    HTTP::uri [ string map {"newFolder" "oldFolder"} [HTTP::uri] ]

     

    set urlRewrite 1

     

    }

     

    }

     

    }

     

     

    when HTTP_RESPONSE_DATA {

     

    rewrite the franchise number back to the name in server response

     

    if { $urlRewrite == 1 } {

     

    regsub -all "/Find" [HTTP::payload] "/ReplaceWith" newdata

     

    regsub -all "/368" [HTTP::payload] "/515" newdata

     

    set clen [HTTP::payload length]

     

    HTTP::payload replace 0 $clen $newdata

     

    HTTP::release

     

    }

     

    }
  • Hi Brandon,

    If it's just the URI in requests and response redirects, you can use something like this:

    when HTTP_REQUEST {
    
     Check the requested URI set to lowercase
    switch -glob [string tolower [HTTP::uri]] {
    "/newfolder/*" {
    set find "newfolder"
    set replace "oldfolder"
    HTTP::uri [ string map -nocase "$find $replace" [HTTP::uri]]
    }
    }
    }
    when HTTP_RESPONSE {
    
     Check if response is a redirect
    if {[HTTP::is_redirect] and [HTTP::header Location] contains $find}{
     Rewrite the redirect Location header value
    HTTP::header replace Location [string map -nocase "$find $replace" [HTTP::header Location]]
    }
    
     Check if response payload type is text
    if {[HTTP::header value Content-Type] contains "text"}{
    
     Set the replacement strings
    STREAM::expression "@$find@$replace@"
    
     Enable the stream filter for this response only
    STREAM::enable
    }
    }
    

    If you need to rewrite response content as well, you can add a blank stream profile, a custom HTTP profile with response chunking set to rechunk and this iRule:

    when HTTP_REQUEST {
    
     Track whether to rewrite responses
    set rewrite 0
    
     Check the requested URI set to lowercase
    switch -glob [string tolower [HTTP::uri]] {
    "/newfolder/*" {
    set find "newfolder"
    set replace "oldfolder"
    HTTP::uri [ string map -nocase "$find $replace" [HTTP::uri]]
    set rewrite 1
    }
    }
    }
    when HTTP_RESPONSE {
    
    if {$rewrite}{
    
     Check if response is a redirect
    if {[HTTP::is_redirect] and [HTTP::header Location] contains $find}{
     Rewrite the redirect Location header value
    HTTP::header replace Location [string map -nocase "$find $replace" [HTTP::header Location]]
    }
    
     Check if response payload type is text
    if {[HTTP::header value Content-Type] contains "text"}{
    
     Set the replacement strings
    STREAM::expression "@$find@$replace@"
    
     Enable the stream filter for this response only
    STREAM::enable
    }
    }
    }
    

    Aaron