Skip to content

About

nginx module that picks a language for the request from Accept-Language, weights respected, into a variable

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

2 Commits

Folders and files

Repository files navigation

nginx-accept-language-module

Build & Test FreeBSD A/UBSan Valgrind Reload CodeQL Lint

Pick a language for the request out of a list the server can serve, from the client's Accept-Language header, into an nginx variable.

http {
    set_from_accept_language $lang de en fr;

    server {
        location / {
            root /var/www/$lang;
        }
    }
}

The directive

set_from_accept_language

syntax: set_from_accept_language $variable <language> [<language> ...] context: http, server, location

Defines $variable and gives it the language from the list that the request asks for. At least one language is required; the first one is what the server prefers.

How the language is picked

The header is a list of candidates, each with an optional weight: Accept-Language: de;q=0.1, en;q=0.9 asks for English and would settle for German.

  • The weight decides. Among the candidates that match the list, the one with the highest q wins. A candidate without q weighs 1, which is the most there is. Three decimals are read, so q=0.334 beats q=0.333.
  • q=0 means no. A candidate the client refuses is never chosen.
  • On equal weight the list decides, not the order of the header: the order a client writes its candidates in says nothing about preference, the weight does. Where the client expressed none, the server's own preference is the next best thing.
  • A region covers its language. A configured de matches de and de-AT, and not denmark: the match has to end at the end of the tag or at a hyphen.
  • * speaks for the first language on the list, which is the server's own choice, and it carries its weight like any other candidate.
  • Anything else answers with the first language on the list: no header, nothing acceptable, or nothing that matches.
  • Case is ignored, as are spaces and tabs around the candidates. A parameter other than q is stepped over. A weight that is not a number leaves the candidate at 1: a client that writes nonsense into one parameter still said which languages it wants.

One variable per http block

nginx variables are per http block, so set_from_accept_language with the same variable twice -- once per server, say -- is refused with "variable already defined", although the directive is allowed in server and location. One variable, one list; two lists need two variables.

Building

ci/build.sh 1.30.5 /tmp/nginx-test            # into the binary
ci/build.sh 1.30.5 /tmp/nginx-test dynamic    # as a loadable object

Testing

ci/build.sh 1.30.5 /tmp/nginx-test
TEST_NGINX_BINARY=/tmp/nginx-test/sbin/nginx prove -r t/

t/quality.t is the one that matters: thirteen headers whose answer is decided by the weights, which is what the module this was taken over from threw away.

License

BSD 2-Clause. The module is Guillaume Maury's; the weighting and the scaffolding around it are under the same terms. See LICENSE.

About

nginx module that picks a language for the request from Accept-Language, weights respected, into a variable

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages