Forum Discussion

mlamutt_62697's avatar
mlamutt_62697
Icon for Nimbostratus rankNimbostratus
Oct 15, 2014

Data group redirection or trim the hostname?

I am new to Irule scripting, and have a quick need for an Irule that redirects to a url based on the incoming uri that has an url (possibly encoded) as the first part of the URI. I was going to use an external data group because the list of redirect will be growing in to the 100s.

 

for example: www.site.com/www.foo.com/content/image.png needs to redirect to : www.foo.com/content/image.png

 

from other posts I started off with this:

 

REQUEST { if { [class match [string tolower [HTTP::uri]] starts_with www.site.com.data.group] } { HTTP::redirect "http://[class match -value [string tolower [HTTP::uri]] starts_with www.site.com.data.group]" } }

 

and the data group has this listed in it: /www.foo.com := www.foo.com.

 

Am I over complicating this? do I need to use a data group, or can this be done with a simple redirect substitution where we basically trim the host name.

 

Any help would be much appreciated.

 

5 Replies

  • Arie's avatar
    Arie
    Icon for Altostratus rankAltostratus

    Updating an external data group (class) is cumbersome; you're better off using an internal class. You mentioned "hundreds" of entries, which really isn't much at all.

    However, as you already suspected it would be much easier to simply manipulate the string.

    However, I'm not entire sure what you're looking for. Is the first folder name (e.g. www.foo.com) always the hostname you want to redirect to? Are there any requests to www.site.com that should not be redirected?

    If the answer to the first question is "yes" and the answer to the second question is "no" you should be able to use this:

     when HTTP_REQUEST {
    
         extract the string between the first and second slash, 
         assuming that this is always the hostname to redirect to.
         Use a skip count of 1 to strip the first slash.
        set hostname [findstr [string tolower [HTTP::path]] "/" 1 "/"]
    
         Remove the hostname part of the uri. Using "string map" 
         because it retains the case of the URI 
         (important for Linux/Apache, and also to retain the case 
         of any query strings)
        set uri [string map -nocase {"/$hostname" ""} [HTTP::uri]]
    
        HTTP::respond 301 Location "http://$hostname$uri"
    
    }
    

    Note: I don't have a BIG-IP handy right now so I didn't test the iRule.

  • Arie's avatar
    Arie
    Icon for Altostratus rankAltostratus

    This should do it. Just create a class (type: string) with the name "class_exceptionList" and populate it with the folder names (in lower case) that shouldn't be redirected.

     when HTTP_REQUEST {
    
         extract the string between the first and second slash, 
         assuming that this is always the hostname to redirect to.
         Use a skip count of 1 to strip the first slash.
        set firstFolder [findstr [string tolower [HTTP::path]] "/" 1 "/"]
    
         Remove the first folder from the uri unless it's listed in the class.
         Using "string map" because it retains the case of the URI.
         (important for Linux/Apache, and also to retain the case 
         of any query strings)
    
        if { [class match $firstFolder equals class_exceptionList } {
    
            set uri [string map -nocase {"/$hostname" ""} [HTTP::uri]]
    
            HTTP::respond 301 Location "http://$firstFolder$uri"
    
        }
    
    }
    
  • Arie's avatar
    Arie
    Icon for Altostratus rankAltostratus

    Ah - I didn't notice that my update hadn't been saved (looks like the forum is having problems). For other members, here's the correct code:

     

     when HTTP_REQUEST {
    
         extract the string between the first and second slash, 
         assuming that this is always the hostname to redirect to.
         Use a skip count of 1 to strip the first slash.
        set firstFolder [findstr [string tolower [HTTP::path]] "/" 1 "/"]
    
         Remove the first folder from the uri unless it's listed in the class.
         Using "string map" because it retains the case of the URI.
         (important for Linux/Apache, and also to retain the case 
         of any query strings)
    
        if { not [class match $firstFolder equals class_exceptionList] } {
    
            set uri [string map -nocase {"/$hostname" ""} [HTTP::uri]]
    
            HTTP::respond 301 Location "http://$firstFolder$uri"
    
        }
    
    }
  • Thanks for all your help. I made a few more changes, but it looks like it is working as needed. Feel free to critique if there are any areas of improvements.

    when CLIENT_ACCEPTED {
    
        Check the VS port to determine if connection is SSL or not
       switch [TCP::local_port] {
          "443" {
             set proto "https"
          }
          default {
             set proto "http"
          }
       }
    
    log local0.  "This is the new protocol - ${proto}"
    
    }
    
    
    when HTTP_REQUEST {
    
         extract the string between the first and second slash, 
         assuming that this is always the hostname to redirect to.
         Use a skip count of 1 to strip the first slash.
        set firstFolder [findstr [string tolower [HTTP::path]] "/" 1 "/"]
    
        log local0.  "This is the domain - $firstFolder" 
    
         Remove the first folder from the uri unless it's listed in the class.
         Using "string map" because it retains the case of the URI.
         (important for Linux/Apache, and also to retain the case 
         of any query strings)
    
        if { not [class match $firstFolder redirect.data.group] } {
    
            set uri [string map -nocase {"/$hostname" ""} [HTTP::uri]]
    
            log local0.  "This is the new uri - $uri"
    
            HTTP::respond 301 Location "${proto}:/$uri"
    
            log local0.  "This is the new url - ${proto}:/$uri"
    
        }
    
    }
    
    • Arie's avatar
      Arie
      Icon for Altostratus rankAltostratus
      Looks good. (If any of my replies answered your initial question, would you mind marking it as the answer? - Thanks!)