From: Darren Date: Wed, 7 May 2014 21:49:13 +0000 (+0100) Subject: Using Negotiator for accept-language parsing X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=88a9b153643f7652534cfd95187658e8633ceaca;p=KiwiIRC.git Using Negotiator for accept-language parsing --- diff --git a/package.json b/package.json index b44c7f5..980ddd0 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "iconv-lite": "0.2.11", "spdy": "1.19.1", "po2json": "0.2.3", + "negotiator": "0.4.3", "winston": "~0.7.2" }, "engines": { diff --git a/server/httphandler.js b/server/httphandler.js index 08b6336..1fdcf95 100644 --- a/server/httphandler.js +++ b/server/httphandler.js @@ -1,6 +1,7 @@ var url = require('url'), fs = require('fs'), node_static = require('node-static'), + Negotiator = require('negotiator'), _ = require('lodash'), config = require('./configuration.js'), SettingsGenerator = require('./settingsgenerator.js'); @@ -62,71 +63,47 @@ HttpHandler.prototype.serve = function (request, response) { }; +// Cached list of available translations +var cached_available_locales = []; + +// Get a list of the available translations we have +fs.readdir('client/assets/locales', function (err, files) { + files.forEach(function (file) { + if (file.substr(-5) === '.json') { + cached_available_locales.push(file.slice(0, -5)); + } + }); +}); + + + /** * Handle the /assets/locales/magic.json request * Find the closest translation we have for the language * set in the browser. **/ var serveMagicLocale = function (request, response) { - var that = this, - default_locale_id = 'en-gb'; + var default_locale_id = 'en-gb', + found_locale, negotiator; if (!request.headers['accept-language']) { // No accept-language specified in the request so send the default - return serveLocale.call(this, request, response, default_locale_id); - } - - fs.readdir('client/assets/locales', function (err, files) { - var available = [], - i = 0, - langs = request.headers['accept-language'].split(','), // Example: en-gb,en;q=0.5 - found_locale = default_locale_id; - - // Get a list of the available translations we have - files.forEach(function (file) { - if (file.substr(-5) === '.json') { - available.push(file.slice(0, -5)); - } - }); - - // Sanitise the browsers accepted languages and the qualities - for (i = 0; i < langs.length; i++) { - langs[i]= langs[i].split(';q='); - langs[i][0] = langs[i][0].toLowerCase(); - langs[i][1] = (typeof langs[i][1] === 'string') ? parseFloat(langs[i][1]) : 1.0; - } - - // Sort the accepted languages by quality - langs.sort(function (a, b) { - return b[1] - a[1]; - }); - - // Serve the first language we have a translation for - for (i = 0; i < langs.length; i++) { - if (langs[i][0] === '*') { - break; - } else if (_.contains(available, langs[i][0])) { - found_locale = langs[i][0]; - break; - } - } - - return serveLocale.call(that, request, response, found_locale); - }); -}; + found_locale = default_locale_id; + } else { + negotiator = new Negotiator(request); + found_locale = negotiator.language(cached_available_locales); + } -/** - * Send a locale to the browser - */ -var serveLocale = function (request, response, locale_id) { - this.file_server.serveFile('/assets/locales/' + locale_id + '.json', 200, { + // Send a locale to the browser + this.file_server.serveFile('/assets/locales/' + found_locale + '.json', 200, { Vary: 'Accept-Language', - 'Content-Language': locale_id + 'Content-Language': found_locale }, request, response); }; + /** * Handle the settings.json request */