Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 0 additions & 45 deletions README

This file was deleted.

69 changes: 69 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
Nginx HTTP Set Lang Module
--------------------------

Description
-----------

An Nginx module that provides a variety of ways for setting a variable denoting the
langauge that content should be returned in.


Methods for setting language variable
-------------------------------------

- cookie
- URL arguments
- Accept-Language header
- geoip
- host
- referer
- POST variables (todo)


Usage
-----

List the supported locales::

lang_list en nl fr;

If you want to read from and write to cookies (``lang`` is the cookie name)::

lang_cookie lang;

To make a (top-level) domain map to a certain locale::

lang_host com en;

And to read the language from the user and put it in a variable::

set_lang '$lang' accept_lang get post cookie geoip host referer default;


Working example::

lang_list en pt_BR;
lang_cookie lang;
set_lang '$lang' cookie accept_lang default;

The example above uses accept-language to give you any supported language.
If no supported language is found than the ``$lang`` variable will be set to the first language in ``lang_list`` (i.e. ``en``).


Installation
------------

./configure --add-module=/path/to/ngx_devel_kit --add-module=/path/to/ngx_http_set_lang



Copyright
---------

- Marcus Clyne (c) 2010
- Rick van Hattem (c) 2011

License
-------

BSD
70 changes: 63 additions & 7 deletions ngx_http_set_lang_module.c
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@

/*
* Copyright (c) 2009 Marcus Clyne
*/


#include <ndk.h>

#define MINUTE 60
#define HOUR 60 * MINUTE
#define DAY 24 * MINUTE
#define YEAR 365 * DAY
#define COOKIE_PARAM_BUFFER 40

// TODO : add setting a variable that dictates the method - $set_lang_method

Expand All @@ -24,6 +28,7 @@ static ngx_int_t ngx_http_set_lang_from_geoip (ngx_http_request_t *r,
static ngx_int_t ngx_http_set_lang_from_host (ngx_http_request_t *r, ngx_http_set_lang_loc_conf_t *conf, ngx_str_t *v);
static ngx_int_t ngx_http_set_lang_from_referer (ngx_http_request_t *r, ngx_http_set_lang_loc_conf_t *conf, ngx_str_t *v);
static ngx_int_t ngx_http_set_lang_from_var (ngx_http_request_t *r, ngx_http_set_lang_loc_conf_t *conf, ngx_str_t *v);
static ngx_int_t ngx_http_set_lang_from_default (ngx_http_request_t *r, ngx_http_set_lang_loc_conf_t *conf, ngx_str_t *v);

static char * ngx_http_set_lang (ngx_conf_t *cf, ngx_command_t *cmd, void *cnf);
static ngx_int_t ngx_http_set_lang_from_methods (ngx_http_request_t *r, ngx_str_t *v);
Expand Down Expand Up @@ -79,6 +84,7 @@ static ngx_http_set_lang_method_t ngx_http_set_lang_methods [] = {
{ngx_http_set_lang_from_geoip, ngx_string ("geoip")},
{ngx_http_set_lang_from_host, ngx_string ("host")},
{ngx_http_set_lang_from_referer, ngx_string ("referer")},
{ngx_http_set_lang_from_default, ngx_string ("default")},
{NULL, ngx_null_string}
};

Expand Down Expand Up @@ -197,6 +203,27 @@ ngx_http_set_lang_from_methods (ngx_http_request_t *r, ngx_str_t *v)
ngx_http_variable_value_t *mv;
ngx_http_set_lang_func_pt func;

// Generate the extra cookie params (path + expires)
static char cookie_params[COOKIE_PARAM_BUFFER];
struct tm timestruct;
time_t now;

// Fetch the current time
time(&now);

// Default the expires date to 1 year in the future
now += YEAR;

// Format the string as RFC 2616 specifies
gmtime_r(&now, &timestruct);

strftime(
cookie_params,
COOKIE_PARAM_BUFFER,
"; path=/; expires=%a, %d %b %Y %H:%M:%S GMT",
&timestruct
);

llcf = ngx_http_get_module_loc_conf (r, ngx_http_set_lang_module);

if (!llcf->enable)
Expand Down Expand Up @@ -224,7 +251,7 @@ ngx_http_set_lang_from_methods (ngx_http_request_t *r, ngx_str_t *v)

// create lang cookie

len = llcf->cookie.len + v->len + sizeof ("; path=/");
len = llcf->cookie.len + v->len + sizeof (cookie_params);

cookie = ngx_pnalloc (r->pool, len + 1);
if (cookie == NULL) {
Expand All @@ -235,7 +262,7 @@ ngx_http_set_lang_from_methods (ngx_http_request_t *r, ngx_str_t *v)
*p++ = '=';

p = ngx_copy (p, v->data, v->len);
p = ngx_copy (p, "; path=/", sizeof ("; path=/"));
p = ngx_copy (p, cookie_params, sizeof (cookie_params));


// add lang cookie to main response
Expand Down Expand Up @@ -375,15 +402,28 @@ ngx_http_set_lang_from_post (ngx_http_request_t *r, ngx_http_set_lang_loc_conf_t
static ngx_int_t
ngx_http_set_lang_from_cookie (ngx_http_request_t *r, ngx_http_set_lang_loc_conf_t *conf, ngx_str_t *v)
{
ngx_str_t cookie;
ngx_str_t cookie, *lang;
ngx_uint_t i;

if (ngx_http_parse_multi_header_lines (&r->headers_in.cookies, &conf->cookie, &cookie) == NGX_DECLINED)
return NGX_DECLINED;

v->data = cookie.data;
v->len = cookie.len;
// compare to lang list

return NGX_OK;
lang = conf->langs->elts;

for (i=conf->langs->nelts; i; i--,lang++) {

if (cookie.len == lang->len && !ngx_strncasecmp (cookie.data, lang->data, cookie.len)) {

v->data = cookie.data;
v->len = cookie.len;

return NGX_OK;
}
}

return NGX_DECLINED;
}


Expand All @@ -399,6 +439,22 @@ ngx_http_set_lang_from_geoip (ngx_http_request_t *r, ngx_http_set_lang_loc_conf_



static ngx_int_t
ngx_http_set_lang_from_default (ngx_http_request_t *r, ngx_http_set_lang_loc_conf_t *conf, ngx_str_t *v)
{
// Default to the first language in the lang_list
ngx_str_t *lang;

lang = ((ngx_str_t *)conf->langs->elts) + (conf->langs->nelts - 1);

v->data = lang->data;
v->len = lang->len;

return NGX_OK;
}



static ngx_int_t
ngx_http_set_lang_from_host (ngx_http_request_t *r, ngx_http_set_lang_loc_conf_t *conf, ngx_str_t *v)
{
Expand Down