when you say “current version”, do you mean the 1.5 dev version?   I’m running 
1.4 right now, but its not production, so I can easily “upgrade” if that is 
required …


On Apr 14, 2014, at 12:30 , Thierry FOURNIER <[email protected]> wrote:

> Hi Marc,
> 
> This dev is done in the current haproxy version. The keyword is
> "language", this is the documentation:
> 
>   language(<value[;value[;value[;...]]]>[,<default>])
>      Returns the value with the highest q-factor from a list as
>      extracted from the "accept-language" header using "req.fhdr".
>      Values with no q-factor have a q-factor of 1. Values with a
>      q-factor of 0 are dropped. Only values which belong to the list of
>      semi-colon delimited <values> will be considered. If no value
>      matches the given list and a default value is provided, it is
>      returned. Note that language names may have a variant after a dash
>      ('-'). If this variant is present in the list, it will be matched,
>      but if it is not, only the base language is checked. The match is
>      case-sensitive, and the output string is always one of those
>      provided in arguments. The ordering of arguments is meaningless,
>      only the ordering of the values in the request counts, as the
>      first value among multiple sharing the same q-factor is used. 
> 
>      Example :
> 
>      # The "language" keyword must take the list of all language that
>      # your load balanced web site support. The list of matched
>      # language must contain all RTL languages.
>      acl rtl req.fhdr(accept-language),language (de;es;fr;en;ar) ar
>      use_backend rtl if rtl default_backend ltr
> 
> Can you test this feature ?
> 
> Thierry
> 
> 
> On Thu, 10 Apr 2014 11:00:38 +0200
> Willy Tarreau <[email protected]> wrote:
> 
>> On Wed, Apr 09, 2014 at 01:50:28PM -0700, Marc Fournier wrote:
>>> nginx has a module for doing this 
>>> (http://wiki.nginx.org/AcceptLanguageModule) that appears to work on a 
>>> ?first match? basis:
>>> 
>>> ==
>>> set_from_accept_language $lang en ja pl;
>>> ==
>>> 
>>> so site supports en/ja/pl ? $lang variable set based on the first
>>> Accept-Languages value that matches that list ? if no match, default to the
>>> first one (en) ?
>>> 
>>> This might be more then could be done in the config file though, if you want
>>> to honor the q= prioritizer, but that is just a method of grouping, from 
>>> what
>>> I?ve read in RFC2616 ? your examples above, for instance, would translate 
>>> as:
>> 
>> You *must* honnor "q=" because "q=0" means that you won't accept the
>> associated value. That's what haproxy does with accept-encoding for
>> example.
>> 
>>>> zh-TW,zh;q=0.8,en-US;q=0.6,en;q=0.4,ar
>>> 
>>> zh-TW;q=1,zh;q=0.8,en-US;q=0.6,en;q=0.4,ar;q=1
>>> 
>>> which would then sort out to:
>>> 
>>> zh-TW,ar,zh,en-US,en
>>> 
>>> Of course, that assumes I?m reading how it works from RFC2616 correctly ?
>>> without any q= value, everything defaults to 1 and is parsed ?in hte order
>>> presented? ? the q= modifier provides a sort order by weighting everything
>>> from ?most desired? to ?least desired? ?
>>> 
>>> Hrmmm ? a bit messy, but what I could probably do is use nginx in front of
>>> haproxy to set a cookie that I could read in haproxy and redirect 
>>> accordingly
>>> ? which I may need to do anyway, to support https:// ? 
>>> 
>>> And yes, I could use nginx to do the load balancing too, but I?m using
>>> haproxy?s stats interface for load monitoring / alerting ? I?d rather avoid
>>> using nginx if I can, since it just adds one more layer ...
>> 
>> Matching a series of q-values is very easy, the difficulty is in defining
>> how we'd like the accepted values to be configured in order to apply the
>> match.
>> 
>> Thierry proposed me something like a sample fetch which would take a
>> semi-colon delimited list of languages. I don't know if that's something
>> acceptable, as I still find that it's not obvious to configure, but it
>> would permit every possible combination. For example you would have :
>> 
>>   use_backend en if  { 
>> req.fhdr(accept-language),q-preferred(zh-TW;ar;zh;en-US;en)  en en-US }
>>   use_backend zh if  { 
>> req.fhdr(accept-language),q-preferred(zh-TW;ar;zh;en-US;en)  zh zh-TW }
>>   use_backend ar if  { 
>> req.fhdr(accept-language),q-preferred(zh-TW;ar;zh;en-US;en)  ar }
>> 
>> So that would extract the complete accept-language header, apply the 
>> filtering
>> from the supported list and pick the preferred one, then match it against a 
>> set
>> of strings.
>> 
>> The benefit of applying it as a converter is that it will be usable as
>> well for accept, accept-charset and accept-encoding.
>> 
>> If that's something you think is acceptable in terms of configuration, I
>> believe it's really not complicated to do given that we already have the
>> code to pick a preferred value in a q-list.
>> 
>> Willy
>> 
>> 


Reply via email to