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