Forum Discussion

Jim_43682's avatar
Jim_43682
Icon for Nimbostratus rankNimbostratus
May 10, 2012

10.2.2 - irule redirect and rewrite not working for non-FQDN requests.

Hello all, I appreciate your help on this. I am trying to trouble shoot an irule script that wrote to do rewrites and redirects depending on if it is http or https. I have created several data groups for the logic. The issue is if a client uses the FQDN it works, but not the common name. For example mysite.mycompany.com works but mysite does not. I have also checked both with nslookup and both resolve to the virtual server with this irule associated with it.

Here is my script:


class data_SharedEnv_Hosts_table {
   {
      "niss.mycompany.com" { "internal.mycompany.com" }
      "preslib.mycompany.com" { "internal.mycompany.com" }
      "selfhelp.mycompany.com" { "internal.mycompany.com" }
      "svcctr.mycompany.com" { "internal.mycompany.com" }
      "technet.mycompany.com" { "internal.mycompany.com" }
   }
}
class data_SharedEnv_internal_URI_table {
   {
      "niss.mycompany.com" { "niss" }
      "preslib.mycompany.com" { "national_accounts/communications/presentation_library" }
      "selfhelp.mycompany.com" { "raportal/ss" }
      "svcctr.mycompany.com" { "sc" }
      "technet.mycompany.com" { "technet" }
   }
}
class data_SharedEnv_isSSL_table {
   {
      "niss.mycompany.com" { "https" }
      "preslib.mycompany.com" { "http" }
      "selfhelp.mycompany.com" { "https" }
      "svcctr.mycompany.com" { "https" }
      "tdm.mycompany.com" { "https" }
      "technet.mycompany.com" { "http" }
      "trg.mycompany.com" { "https" }
   }
}
rule irule_SharedEnv_rewrite_redirect {
when HTTP_REQUEST {
get user hostheader
set originalHost [string tolower [HTTP::host]]
check if rewrite or redirect is applicable
if { [matchclass $originalHost starts_with $::data_SharedEnv_Hosts_table  ]}{
        if { [class match -value -- $originalHost starts_with data_SharedEnv_isSSL_table] == "http"}{
                get SharedEnv DNS value from data_SharedEnv_Hosts_table  
                set sharedEnvHost [class match -value -- $originalHost starts_with data_SharedEnv_Hosts_table ]
                
                get URI from table
                switch $sharedEnvHost {
                        "internal.mycompany.com" {
                        set baseURI [class match -value -- $originalHost starts_with data_SharedEnv_internal_URI_table]
                        }
                        default {
                        set baseURI ""
                        }
                }
                
                Replace the host header value with $sharedEnvHost value and use the the baseURI
                HTTP::header replace Host $sharedEnvHost
                HTTP::uri "/$baseURI/[HTTP::uri]"  
        }
        if { [class match -value -- $originalHost contains data_SharedEnv_isSSL_table ] == "https"}{
                get SharedEnv DNS to use
                set sharedEnvHost [class match -value -- $originalHost starts_with data_SharedEnv_Hosts_table ]
                
                get URI table to use
                switch $sharedEnvHost {
                        "internal.mycompany.com" {
                         set baseURI [class match -value -- $originalHost starts_with data_SharedEnv_internal_URI_table]       
                        }
                        default {
                        set baseURI ""
                        }
                }
                redirect using $sharedEnv and $baseURI
                HTTP::redirect "https://$sharedEnvHost/$baseURI[HTTP::uri]"
        }
} elseif { ! [string match ".mycompany.com" $originalHost]}{
     HTTP::redirect "http://$originalHost.mycompany.com"
}       
}

  • George_Watkins_'s avatar
    George_Watkins_
    Historic F5 Account
    Hi Jim,

    The easiest way to make this iRule work with unqualified hostnames is to just append the domain to the $originalHost variable if it doesn't already exist. I added a conditional to accomplish this:

    if hostname is not fully-qualified append the domain
    if { !($originalHost ends_with $static::mydomain) } { append originalHost ".$static::mydomain" } 
    I also changed matchclass to the class command on line 13. The matchclass command has been deprecated and its usage is discouraged. Likewise, the $:: method for referencing data groups has also been deprecated. The line changed from:
    if { [matchclass $originalHost starts_with $::data_SharedEnv_Hosts_table  ]}{ 
    to:
    if { [class match $originalHost starts_with data_SharedEnv_Hosts_table]}{ 
    Lastly, I added a static variable for your domain name so you only have to define it once in your rule. I also replaced all of the occurrences of "mycompany.com" with $static::mydomain. The final iRule looks like this:
    when RULE_INIT {
        set static::mydomain "mycompany.com"
    }
        
    when HTTP_REQUEST {
        get user hostheader
        set originalHost [string tolower [HTTP::host]]
    
        if hostname is not fully-qualified append the domain
        if { !($originalHost ends_with $static::mydomain) } { append originalHost ".$static::mydomain" }
    
        check if rewrite or redirect is applicable
        if { [class match $originalHost starts_with data_SharedEnv_Hosts_table]} {
            if { [class match -value -- $originalHost starts_with data_SharedEnv_isSSL_table] == "http"} {
                get SharedEnv DNS value from data_SharedEnv_Hosts_table  
                set sharedEnvHost [class match -value -- $originalHost starts_with data_SharedEnv_Hosts_table ]
                
                get URI from table
                switch $sharedEnvHost {
                    "internal.$static::mydomain" {
                        set baseURI [class match -value -- $originalHost starts_with data_SharedEnv_internal_URI_table]
                    }
                    default {
                        set baseURI ""
                    }
                }
                
                Replace the host header value with $sharedEnvHost value and use the the baseURI
                HTTP::header replace Host $sharedEnvHost
                HTTP::uri "/$baseURI/[HTTP::uri]"  
            }
            if { [class match -value -- $originalHost contains data_SharedEnv_isSSL_table ] == "https"}{
                get SharedEnv DNS to use
                set sharedEnvHost [class match -value -- $originalHost starts_with data_SharedEnv_Hosts_table ]
                
                get URI table to use
                switch $sharedEnvHost {
                    "internal.$static::mydomain" {
                        set baseURI [class match -value -- $originalHost starts_with data_SharedEnv_internal_URI_table]       
                    }
                    default {
                        set baseURI ""
                    }
                }
                redirect using $sharedEnv and $baseURI
                HTTP::redirect "https://$sharedEnvHost/$baseURI[HTTP::uri]"
            }
        } elseif { ! ($originalHost ends_with ".$static::mydomain") }{
         HTTP::redirect "http://$originalHost.$static::mydomain"
        }       
    }
    Hope that helps, -George