Forum Discussion

Puli's avatar
Puli
Icon for Nimbostratus rankNimbostratus
Mar 31, 2011

iRule to detect browser language and re-direct

Am working an iRule to detect browser's language and re-direct to the appropriate help page.

 

 

For example

 

www.abc.com browser language is french send it to www.abc.com/fr/help

 

 

Can you provide me with sample code how i can achieve this.

 

 

Can you recommend any tool to test it? to change my browser language for testing purposes ?

 

 

thanks, appreciate it.

 

Puli.

 

 

  • Hi Puli,

     

    You can pull this from the HTTP header fields.

     

     

    Specifically HTTP header field called Accept-language header

     

    Click Here to go to a link that discusses accept-language header

     

     

    As for the code I suppose you can use a untested iRule scripts like the following

     

     

    
    when HTTP_REQUEST {
    
          if { [HTTP::header "Accepted-Language"] contains "fr" }  {
    
               HTTP::redirect http://www.abc.com/fr/help
         
             }
    
    }

     

     

    or you can go switch command route if you have many different language pages.

     

     

    
    when HTTP_REQUEST {
       
          switch -glob [HTTP::header "Accepted-Language"] {
          
         "*fr*" - { HTTP::redirect http://www.abc.com/fr/help }
          
         "*en-us*" - { HTTP::redirect http://www.abc.com/fr/help }
    
          default - { HTTP::redirect http://www.abc.com/help }
       
          }
    
    }
    

     

     

    The tool that I normally use is the HTTPFox to quickly look at the language my browser is set to. Click Here to see view how you can switch languages on the browser level.

     

     

    I hope this helps

     

    Bhattman

     

  • Colin_Walker_12's avatar
    Colin_Walker_12
    Historic F5 Account
    Keep in mind both of those examples are using a "contains" style match, which means you're not necessarily using their preferred language, just one that they support. To be more specific you'd want to find the first language in the list.

     

     

    Colin
  • You'd probably also want to only check a few URIs (/ and the main index page come to mind) so you're not checking the header on every request. Also, if the help pages are on the same VS as this iRule, you'd need some kind of logic to avoid a loop of redirects.

    You can use Fiddler (or an iRule even) to manipulate the Accept-Language header value: HTTP::header replace Accept-Language "my-new-language"

    To add to Colin's point, the Accept-Language header can have a preferential list:

    http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

    14.4 Accept-Language

    The Accept-Language request-header field is similar to Accept, but restricts the set of natural languages that are preferred as a response to the request. Language tags are defined in section 3.10.

    Accept-Language = "Accept-Language" ":"

    1( language-range [ ";" "q" "=" qvalue ] )

    language-range = ( ( 1*8ALPHA *( "-" 1*8ALPHA ) ) | "*" )

    Each language-range MAY be given an associated quality value which represents an estimate of the user's preference for the languages specified by that range. The quality value defaults to "q=1". For example,

    Accept-Language: da, en-gb;q=0.8, en;q=0.7

    would mean: "I prefer Danish, but will accept British English and other types of English." A language-range matches a language-tag if it exactly equals the tag, or if it exactly equals a prefix of the tag such that the first tag character following the prefix is "-". The special range "*", if present in the Accept-Language field, matches every tag not matched by any other range present in the Accept-Language field.

    Note: This use of a prefix matching rule does not imply that

    language tags are assigned to languages in such a way that it is

    always true that if a user understands a language with a certain

    tag, then this user will also understand all languages with tags

    for which this tag is a prefix. The prefix rule simply allows the

    use of prefix tags if this is the case.

    The language quality factor assigned to a language-tag by the Accept-Language field is the quality value of the longest language- range in the field that matches the language-tag. If no language- range in the field matches the tag, the language quality factor assigned is 0. If no Accept-Language header is present in the request, the server

    SHOULD assume that all languages are equally acceptable. If an Accept-Language header is present, then all languages which are assigned a quality factor greater than 0 are acceptable.

    It might be contrary to the privacy expectations of the user to send an Accept-Language header with the complete linguistic preferences of the user in every request. For a discussion of this issue, see section 15.1.4.

    As intelligibility is highly dependent on the individual user, it is recommended that client applications make the choice of linguistic preference available to the user. If the choice is not made available, then the Accept-Language header field MUST NOT be given in the request.

    Note: When making the choice of linguistic preference available to

    the user, we remind implementors of the fact that users are not

    familiar with the details of language matching as described above,

    and should provide appropriate guidance. As an example, users

    might assume that on selecting "en-gb", they will be served any

    kind of English document if British English is not available. A

    user agent might suggest in such a case to add "en" to get the

    best matching behavior.

    Here's a blog showing a method for parsing the header:

    http://www.thefutureoftheweb.com/blog/use-accept-language-header

    I think you could probably cheat a bit and just look at the first language up to the first comma and switch on that:

    switch -glob [getfield [HTTP::header Accept-Language] "," 1]

    Of you could read these into a TCL list and evaluate them one by one until you find a match:

    
    foreach line [split [HTTP::header Accept-Language] "," ] {
       switch -glob [getfield $line ";" 1] {
          "de*" {
    
             ...
    
              Break out of the loop as we found a match
             break
       }
    }
    

    I could see this looping being expensive though.

    Aaron
  • Colin_Walker_12's avatar
    Colin_Walker_12
    Historic F5 Account
    @Aaron - Agreed on the loop being expensive. It's likely an unnecessary cost, too. You could easily get the first entry or two without having to loop through the entire header. You'd save cycles and lose effectively no functionality that way.

     

     

    Thanks for fishing out the RFC, I wasn't going to bother. ;)

     

     

    Colin
  • Puli's avatar
    Puli
    Icon for Nimbostratus rankNimbostratus
    I agree Aaron, just looking at the first language entry and switch will be less expensive.

     

    Thanks Bhattman, colin and Aaron for you input.

     

     

    this was really helpful.

     

    Appreciate your time.

     

     

    Puli.
  • Puli's avatar
    Puli
    Icon for Nimbostratus rankNimbostratus
    Found this useful add-on on firefox to switch you browser locales to different languages.

     

    I was able to test all my re-direct using this local switcher.

     

     

    https://addons.mozilla.org/en-us/firefox/addon/quick-locale-switcher