Forum Discussion

Joe_Pipitone's avatar
Joe_Pipitone
Icon for Nimbostratus rankNimbostratus
Jun 08, 2011

Rewriting only part of the URI

I have a request to rewrite only a certain part of our URI, while still passing the last part of the URI. I need to be able to catch all requests and rewrite just part of the URI.

 

 

I have a script already in use that does something similar, but saves the leading digits based on a specific length of the filename. In this case, all articles have a different number of characters, therefore I cannot use that rule.

 

 

 

I'd be thankful if anyone could point me in the right direction. Here's an example:

 

 

 

 

 

 

 

FROM:

 

 

 

http://ourdomain.com/newsletters/Directory2/*

 

 

 

TO:

 

 

 

http://ourdomain.com/newsletters/Directory3/*

 

 

 

 

 

 

 

The asterisk implies that we need to take the name of the article and pass it along as well, while simply rewriting Directory2 to Directory3:

 

 

 

 

 

FROM:

 

 

 

http://ourdomain.com/newsletters/Directory2/some-article.aspx

 

 

 

TO:

 

 

 

http://ourdomain.com/newsletters/Directory3/some-article.aspx

 

 

 

 

 

 

Perhaps I am thinking way too hard about this. I need to try and preserve everything EXCEPT for the directory after /newsletters/. I can't just pass:

 

 

 

http://ourdomain.com/newsletters/Directory3/[HTTP::uri]

 

 

 

as this would duplicate part of the URI making it look like this:

 

 

 

http://ourdomain.com/newsletters/Directory2/newsletters/Directory3/some-article.aspx

 

 

 

So that's why I'm a bit confused....Do I need to perform some sort of scanning using the URI basename, or simply rewrite based on the URI::path?

 

 

 

 

 

 

 

I appreciate any help!

 

 

 

 

 

 

 

 

 

  • I think I've got it - I simply used a string map, and incorporated HTTP::redirect vs HTTP::path as to perform the rewrite / redirect.

     

     

    when HTTP_REQUEST {

     

     

     

    Check if path starts with /newsletters/Directory2

     

    if {[HTTP::path] starts_with "/newsletters/Directory2"}{

     

     

    Replace /newsletters/Directory2 with /newsletters/Directory3 in the path

     

    HTTP::redirect [string map {/newsletters/Directory2 /newsletters/Directory3} [HTTP::path]]

     

    }

     

    }

     

     

     

     

     

  • So with something static like /newsletters/ beginning your URI, you could do a string range (in tlcsh):

    
    set x "/newsletters/Directory2/something/else/entirely/file.txt"
    puts "/newsletters/Directory3[string range $x [string first / $x 13] end]"
    
    /newsletters/Directory3/something/else/entirely/file.txt
    
  • so in iRules, that would be

    
    HTTP::uri "/newsletters/Directory3[string range $x [string first / $x 13] end]"
    

    might need tweaking if not as static as you presented in the request, but gets you along the way...
  • For some reason, when I start adding on string tolower, I keep getting redirect loops. I want to be sure I catch any case in the browser and set it to lowercase - any idea what I may be missing here?

    when HTTP_REQUEST { 
      
       Check if path starts with /newsletters/directory2 
        if { [string tolower [HTTP::path]] starts_with "/newsletters/directory2"}{ 
      
            Replace /newsletters/directory2 with /newsletters/directory3 in the path 
           HTTP::redirect [string map {/newsletters/directory2 /newsletters/directory3} [HTTP::path]] 
        }
     } 
  • OK - I think I got it again - unless someone sees a problem with this performance wise:

    when HTTP_REQUEST { 
      
       Check if path starts with /newsletters/directory2 
        if { [string tolower [HTTP::path]] starts_with "/newsletters/directory2"}{ 
      
            Replace /newsletters/directory2 with /newsletters/directory3 in the path 
           HTTP::redirect [string map {/newsletters/directory2 /newsletters/directory3} [string tolower [HTTP::path]] ] 
        }
     }
  • hoolio's avatar
    hoolio
    Icon for Cirrostratus rankCirrostratus
    Hi Joe,

     

     

    Jason's example using string range is more exact and possibly slightly more efficient. But if the string map is working for you it should be fine.

     

     

    Aaron
  • Hmm....will his example work if the length of the entire path varies? When I saw the [string first / $x 13], I was under the impression that it would only replace X number of characters...

     

     

    Here's a few example paths:

     

     

    http://ourdomain.com/newsletters/directory3/2011/04/20110420.aspx

     

     

    and

     

     

    http://ourdomain.com/newsletters/directory3/2011/04/20/asomewhat-long-pathforthe-file-tryingtoreach.aspx

     

     

    As always, your help is greatly appreciated. The string map is working great for me so far, the F5's are still sleeping....
  • so what the string range is doing is taking all the content immediately after /newsletters/directory2. The string first is finding the appropriate start index for the string range by looking for the first "/" in HTTP::uri AFTER the first 13 characters. So this could be /newsletters/ or anything else that was 13 characters long. If it was going to be dynamic in length, then you would want to utilize URI::path and string length as part of the equation, then you wouldn't need to specify newsletter/directory2 at all. Fun stuff!