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