Forum Discussion

Bob_10976's avatar
Bob_10976
Icon for Nimbostratus rankNimbostratus
May 20, 2011

Add a Trailing Slash to the URL

Hello all,

I'm needing to covert an ISAPI rule that adds a trailing slash to the end of a url to an iRule, however the tricky part here is i'll need to add in a few exceptions URLs.

For example if you go to my URL https://secure.mydomain.com/shopping the ISAPI rule auto adds the trailing slash "/" on the end which is fine for nearly all my URIs, but I have a few such as that I do not what the trailing slash to be added.

I have copied the ISAPI rule below for reference of what I'm attempting to do with the LTM and iRules


RewriteCond Host: (.*) 
RewriteRule ([^.]+[^/.]) http\://$1$2/ [I,R] 
RewriteCond Host: secure\.mydomain\.com
Any thoughts or suggestions?

Thanks,

Bob

12 Replies

  • Hi Bob,

    Give this a untested irule a try

    The following is a datagroup

    class slashblacklist {

    "/cart"

    }

    The following is the iRule.

    
    when HTTP_REQUEST {
      
       set bl [findclass [HTTP::uri] $::slashblacklist]
    
        if { ([HTTP::uri] eq $bl) and (!([HTTP::uri] ends_with "/"))  } {
        HTTP::uri "[HTTP::uri]/"
      
        }
    
    } 
    

    I hope this helps

    Bhattman
  • Bhattman...Thanks for the info. However I had a couple of quick follow up questions..

     

     

    I've never created a Datagroup before, but understand I can do that in the GUI under iRules->Datagroup List. But which option do I need to select: Integer, String or Address?

     

     

    Also does this rule append the trailing slash to all URI in the assoicated Virtual Server, with the exception of ones that end in /cart?

     

     

    Thanks again!

     

    Bob
  • Guess I spoke to soon, I went and read through the Wiki Class and I see I don't need to create a datagroup...

     

     

    Although I'm getting the following error when I do the check for vaild iRule button in the editor.

     

     

    line 1: [command is not valid in the current scope] [class slashblacklist {

     

     

    Thoughts?

     

     

     

    Thanks

     

    Bob

     

  • You can create a string datagroup in the GUI with your URI tokens that shouldn't have the trailing slash added to. Which LTM version are you running? For 10.x, you'd want to use the class command to look up the requested URI in the datagroup. For 9.x you could use matchclass.

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

    Note, you must be on 10.2.1HF1 or higher to use HTTP::path like this:

    CR142756 - Using HTTP::path to set the path truncates the query string in v10.0 - v10.2.1 (fixed in 10.2.1HF1)

    
    when HTTP_REQUEST {
        Check if the HTTP path is not in the datagroup and does not already end with a /
       if { not ([class match [HTTP::path] equals slashblacklist]) and not ([HTTP::path] ends_with "/")} {
           Append 
          HTTP::path "[HTTP::path]/"
       }
    } 
    

    Aaron
  • Thanks for the reply Aaron.. I'm using 10.2.0 w/ HF1.

     

     

    To be honest I'm still a bit confused. I read through the Wiki on Class but I'm still not sure what I'm suppose to do in the GUI. If my URL is https://secure.mydomain.com/store/cart do I put "/store/cart" or simply "/cart" in the String or the Value box for the Data Group List. Sorry I'm a bit of a noob when it comes to anything coding.

     

     

    Also I do plan on upgrading the LTM to the latest and greatest build in the near future, but I'd like to get this task completed first. If I upgrade, do I need to worry about screwing this up?

     

     

    Thanks again for all the help!

     

     

    Bob
  • This is how I do it on v11 (protocol var is from another iRule):

    set uri_base [URI::basename [HTTP::path]]
    if {$uri_base equals ""} {
       The URI::basename is /folder/
    } elseif {$uri_base contains "."} {
       The URI::basename is *.* file
    } else {
      HTTP::path "[HTTP::path]/"
      HTTP::respond 301 "Location" "${protocol}://[HTTP::host][HTTP::path]"
      return
    }
    
    • Stanislas_Piro2's avatar
      Stanislas_Piro2
      Icon for Cumulonimbus rankCumulonimbus

      Hi Vova,

      do not redirect to

      ${protocol}://[HTTP::host][HTTP::path]
      but to
      [HTTP::path]

      there is no need to send to the client the protocol and the server name of the next resource, the client will request with the same protocol and server name as the current one.

      with this format, you optimize F5 performance and you prevent rewrite tasks on reverse proxy if there is one with different hostname.

    • Vova_200520's avatar
      Vova_200520
      Icon for Altostratus rankAltostratus

      Kai, yep, that's the one :)

       

      Stanislas, thanks, will keep that in mind.