For more information regarding the security incident at F5, the actions we are taking to address it, and our ongoing efforts to protect our customers, click here.

Forum Discussion

Greg_33932's avatar
Greg_33932
Icon for Nimbostratus rankNimbostratus
Feb 27, 2014

IRule - combine 2 variables with an and && statment

Having issues with an irule. I'm no where an expert so please forgive my ignorance. Everything else works but the following statement (bolded is the new portion, rest is working): if { ( $redirect_to_mobile == "true" && [matchclass [$lower_uri] starts_with $group] } {

Basically I want to detect the user browser (iphone, etc.) AND detect the url they are hitting and based on that forward them to the mobile friendly site.

Complete IRule:

when HTTP_REQUEST {

Set the user-agent field to all lower case so that the data group matches are not case sensitive

set user_agent [string tolower [HTTP::header User-Agent]] set non_mobile_pool "www.ddd.com" set mobile_url "http://m.ddd.com" set redirect_to_mobile "false" set group $::group_web_uri_dddMobile

Determine if the user agent (all lower case) is a member of the data group if { [matchclass $user_agent contains $::group_web_mobile_user_agents] } { log local0. "dddMobile - User-agent ($user_agent) is a member of the group_mobile_user-agents data group" set redirect_to_mobile "true"

   Check to see if it is an Android tablet. If it is, do not send it to the mobile site
  if { ( $user_agent contains "android" ) && not ( $user_agent contains "mobile" ) } {
      log local0. "dddMobile - User-agent ($user_agent) contains Android but is not Mobile"  
     set redirect_to_mobile "false"
  }

} else { log local0. "dddMobile - User-agent ($user_agent) is NOT a member of the group_mobile_user-agents data group" set redirect_to_mobile "false" }

Now send the request to the appropriate destination based upon the value of the redirect_to_mobile variable if { ( $redirect_to_mobile == "true" && [matchclass [$lower_uri] starts_with $group] } { HTTP::redirect "$mobile_url[HTTP::uri]"

} else { pool $non_mobile_pool }

}

13 Replies

  • Thanks the above worked out (with exception I forgot to set the agent group), now the my app team is asking for more... Is their a way to have the URL redirect after all the other rules have been executed? They want the url redirected to the mobile site and they want to allow non-group listed items to the main URL (desktop site). The reason is the mobile site is hosted externally and does not have a good 404 page. I'll explain more, please see below process. I hope it helps.

     

    Rundown of the rule explained: 1. detect mobile device based on group set true 1a. detect non-mobile devices Desktop systems set false 2. if mobile device and uri starts with group list - redirect to mobile site above is working, below is new 3. allow non-group listed uri's through 4. redirect the main url "only" mobile site. When we hit the main url it does not redirect as its not in the uri list.

     

    Below is the code I've worked out, however not sure about the last 2 parts.

     

    when CLIENT_ACCEPTED {
    
        set group "group_web_uri_bbbMobile"
        set group_web_mobile_user_agents "group_web_mobile_user_agents"
    }
    when HTTP_REQUEST {
    
         Set the user-agent field to all lower case so that the data group matches are not case sensitive
    
        set user_agent [string tolower [HTTP::header User-Agent]] 
        set urlsite "qa.bbb.com" 
        set non_mobile_pool "qa.bbb.com" 
        set mobile_url "http://mobileqa.bbb.com" 
        set redirect_to_mobile "false" 
        set group_mobile_sites $::group_web_uri_bbbMobile
        set group_web_mobile_user_agents $::group_web_mobile_user_agents
    
         Determine if the user agent (all lower case) is a member of the data group 
      if { [class match $user_agent contains $group_web_mobile_user_agents] } { 
    
             log local0. "bbbMobile - User-agent ($user_agent) is a member of the group_mobile_user-agents data group" 
            set redirect_to_mobile "true"
             Check to see if it is an Android tablet. If it is, do not send it to the mobile site
            if { ( $user_agent contains "android" ) && not( $user_agent contains "mobile" ) } {
                 log local0. "bbbMobile - User-agent ($user_agent) contains Android but is not Mobile"  
                set redirect_to_mobile "false"
            }
        } else { 
             log local0. "bbbMobile - User-agent ($user_agent) is NOT a member of the group_mobile_user-agents data group" 
            set redirect_to_mobile "false" 
        }
    
         Now send the request to the appropriate destination based upon the value of the redirect_to_mobile variable 
      if { ( $redirect_to_mobile == "true" && [class match [string tolower [HTTP::uri]] starts_with $group_mobile_sites] ) } {
           HTTP::redirect "$mobile_url[HTTP::uri]"
    
     } elseif { ( $redirect_to_mobile == "true" && not [class match [string tolower [HTTP::uri]] starts_with $group_mobile_sites] ) } {
           pool $non_mobile_pool
    
     } elseif { ( $redirect_to_mobile == "true"  ) } {
           HTTP::redirect "$mobile_url[HTTP::uri]"
    }
    }
  • just a few of comments.

    1) beginning in 9.4.4, $:: prefix is no longer needed to reference data group. data group is now cmp compatible.

      set group_mobile_sites $::group_web_uri_bbbMobile
      set group_web_mobile_user_agents $::group_web_mobile_user_agents
    

    CMP Compatibility (Class / Data Group List References section)

    https://devcentral.f5.com/wiki/iRules.cmpcompatibility.ashx

    2) string operator (eq) should be used when comparing string

    Polymorphism - Making TCL operators work for you by Colin Walker

    https://devcentral.f5.com/articles/polymorphism-making-tcl-operators-work-for-you.U1iIr1dhcdU

    3) is this condition checking correct? i think the last elseif won't be matched.

      if { ( $redirect_to_mobile == "true" && [class match [string tolower [HTTP::uri]] starts_with $group_mobile_sites] ) } {
        HTTP::redirect "$mobile_url[HTTP::uri]"
    
      } elseif { ( $redirect_to_mobile == "true" && not [class match [string tolower [HTTP::uri]] starts_with $group_mobile_sites] ) } {
        pool $non_mobile_pool
    
      } elseif { ( $redirect_to_mobile == "true"  ) } {
        HTTP::redirect "$mobile_url[HTTP::uri]"
      }
    

    could it be something like this?

      if { $redirect_to_mobile eq "true" } {
        if { [class match [string tolower [HTTP::uri]] starts_with group_web_uri_bbbMobile] } {
          HTTP::redirect "$mobile_url[HTTP::uri]"
        } else {
          pool $non_mobile_pool
        }
      } 
    

    hope this helps.