Forum Discussion

Adam_Borders_10's avatar
Adam_Borders_10
Icon for Nimbostratus rankNimbostratus
Aug 18, 2011

iRule Newbie learning - need validation

I want to validate the this iRule will do as I think. What I want to do is evaluate the request for a redirect to https. If the user connects to domain.com instead of www.domain.com I want to add the www. during the redirect.

 

 

http://www.mydomain.com -> https://www.mydomain.com

 

http://mydomain.com -> https://www.mydomain.com

 

 

 

The Rule:

 

 

 

when HTTP_REQUEST {

 

if { not ([string tolower [HTTP::host]] starts_with "www.")}{

 

HTTP::redirect "https://www.[HTTP::host][HTTP::uri]"

 

}

 

else{

 

HTTP::redirect https://[getfield [HTTP::host] ":" 1][HTTP::uri]

 

}

 

 

 

 

 

 

Thanks for all your help on this in advanced. I don't have much of a dev area to play with yet so I am trying to be careful before deploying any of these.

 

 

 

Adam Borders

 

  • Hi Adam,

    That looks like a good start. You may also want to handle requests with an IP address in the host header or no value:

    when HTTP_REQUEST {
    
       switch -glob [string tolower [HTTP::host]] {
          "www.*" {
              Host started with "www.".  Allow request without redirecting it?
          }
          "*[a-z]*" {
              Host is not null and not an IP address
             HTTP::redirect https://[getfield [HTTP::host] ":" 1][HTTP::uri]
          }
          default {
              Host is null or an IP address
             HTTP::redirect "https://default.example.com[HTTP::uri]"
          }
       }
    }
    

    Aaron
  • Is there a way I can make this more generic? I would love to be able to set this as a rule I can use on all of my SSL VS without modifying it for each one.

     

     

    Thanks,

     

     

     

    Adam Borders

     

  • What would you like to redirect requests to if they are to an IP address? Maybe to that same IP, but via HTTPS?

    What about requests with no host header value? What would you like to redirect them to? Most browsers set the host header to an IP if that was what was used. But custom clients may not. Do you use public IP addresses for your virtual servers? If so, you could redirect the client to the virtual server IP over https:

    when HTTP_REQUEST {
    
       switch -glob [string tolower [HTTP::host]] {
          "www.*" {
              Host started with "www.".  Allow request without redirecting it?
          }
          "*[a-z]*" {
              Host is not null and not an IP address
             HTTP::redirect https://[getfield [HTTP::host] ":" 1][HTTP::uri]
          }
          "" {
              Host is null
             HTTP::redirect "https://default.example.com[HTTP::uri]"
          }
          default {
              Host is an IP address
             HTTP::redirect "https://[HTTP::host][HTTP::uri]"
          }
       }
    }
    

    If you're not concerned about requests with no host header, you could remove the redirect to the hardcoded hostname.

    Aaron

  • If you would like to cut down on the number of comparisons:
    
    
    when HTTP_REQUEST {
    
      switch -glob [string tolower [HTTP::host]] {
        "*[a-z]*" {
           Host is hostname, redirect.
          HTTP::redirect https://www.[string trimleft [HTTP::host] "www."][HTTP::uri]
        }
        "" {
           Host is null
          HTTP::redirect "https://default.example.com[HTTP::uri]"
        }
        default {
              Host is an IP address
             HTTP::redirect "https://[HTTP::host][HTTP::uri]"
        }
    
      }
    
    
    
    

    }

     

  • Hoolio-

    I'm not too worried about people connecting by IP at this time. I will keep it in mind though. Also all of the public addresses for our sites are translated on a firewall before hitting the F5, so I'm not sure the IP redirect would work.

    I also have a series of sites under one SAN cert so I would not want to redirect to just one host.

    @bmoran- can you explain how this line works? Are you taking every host request and if it has the www. on it, strip it off and add the https://www.?

    HTTP::redirect https://www.[string trimleft [HTTP::host] "www."][HTTP::uri]

    Thanks again,

    Adam

  • @bmoran- can you explain how this line works? Are you taking every host request and if it has the www. on it, strip it off and add the https://www.?

     

     

    HTTP::redirect https://www.[string trimleft [HTTP::host] "www."][HTTP::uri]

     

     

     

    That's exactly it. I'm not sure whether that's more efficient than having a separate switch case for host values starting with www., but you have a good understanding of what that line is doing.

     

     

    Aaron
  • Actually, I was wrong on this. string trim will remove any instances of individual characters--not just the literal string of "www.". So if your host starts with a w that isn't www., you will get an unintended result:

    % string trimleft wily.example.com www.

    ily.example.com

    Here is a more accurate option using scan:

    
    set host [string tolower [HTTP::host]]
    if {[scan $host {www.%s} host_no_www] == 1 }{
       set host $host_no_www
    }
    log local0. "\$host: $host"
    

    Aaron