diff --git a/server/src/middleware/l10n.js b/server/src/middleware/l10n.js new file mode 100644 index 0000000000..ab5acd0285 --- /dev/null +++ b/server/src/middleware/l10n.js @@ -0,0 +1,28 @@ +require("../logging").installConsoleHandler(); +const mozlog = require("../logging").mozlog("l10n-middleware"); +const accepts = require("accepts"); +const l10n = require("../l10n"); + +// Get an ordered list of user-preferred locales from the Accept-Language header +exports.getLanguages = function(req) { + let languages = accepts(req).languages(); + // 'accepts' returns '*' if no Accept-Language header was passed. Use English + // as a default instead. #3231 + if (languages[0] === '*') { + languages = ['en-US']; + } + return languages; +}; + +exports.l10n = function(req, res, next) { + l10n.init().then(() => { + let languages = exports.getLanguages(req); + req.getText = l10n.getText(languages); + req.userLocales = l10n.getUserLocales(languages); + req.messages = l10n.getStrings(languages); + next(); + }).catch(err => { + mozlog.error("l10n-middleware-error", {msg: "Error initializing l10n", description: err}); + process.exit(2); + }); +}; diff --git a/server/src/server.js b/server/src/server.js index 15c9e7b00a..3a310c6150 100644 --- a/server/src/server.js +++ b/server/src/server.js @@ -1,7 +1,6 @@ const config = require("./config").getProperties(); require("./logging").installConsoleHandler(); const mozlog = require("./logging").mozlog("server"); -const accepts = require("accepts"); const path = require('path'); const { readFileSync, existsSync } = require('fs'); const Cookies = require("cookies"); @@ -45,7 +44,7 @@ const { captureRavenException, sendRavenMessage, const { errorResponse, simpleResponse, jsResponse } = require("./responses"); const selfPackage = require("./package.json"); const { b64EncodeJson, b64DecodeJson } = require("./b64"); -const l10n = require("./l10n"); +const { l10n } = require("./middleware/l10n"); const PROXY_HEADER_WHITELIST = { "content-type": true, @@ -269,18 +268,7 @@ app.use(function(req, res, next) { next(); }); -app.use(function(req, res, next) { - l10n.init().then(() => { - const languages = accepts(req).languages(); - req.getText = l10n.getText(languages); - req.userLocales = l10n.getUserLocales(languages); - req.messages = l10n.getStrings(languages); - next(); - }).catch(err => { - mozlog.error("l10n-error", {msg: "Error initializing l10n", description: err}); - process.exit(2); - }); -}); +app.use(l10n); app.param("id", function(req, res, next, id) { if (/^[a-zA-Z0-9]{16}$/.test(id)) { diff --git a/test/server/unit/middleware/l10n-test.js b/test/server/unit/middleware/l10n-test.js new file mode 100644 index 0000000000..44843c98fd --- /dev/null +++ b/test/server/unit/middleware/l10n-test.js @@ -0,0 +1,33 @@ +const assert = require('assert'); +const l10n = require('../../../../server/src/middleware/l10n.js'); + +/* globals describe, it */ + +describe('l10n middleware', () => { + describe('getLanguage function (Accept-Language header parsing)', () => { + it('should return ["en-US"] if Accept-Language header is missing', () => { + let mockRequest = { headers: {} }; + let results = l10n.getLanguages(mockRequest); + assert(results.length === 1); + assert.equal('en-US', results[0]); + }); + it('should return ["en-US"] if Accept-Language header value is "*"', () => { + let mockRequest = { headers: { 'accept-language': '*' }}; + let results = l10n.getLanguages(mockRequest); + assert(results.length === 1); + assert.equal('en-US', results[0]); + }); + it('should return ["en-US"] if Accept-Language header value is "en-CA"', () => { + let mockRequest = { headers: { 'accept-language': 'en-CA' }}; + let results = l10n.getLanguages(mockRequest); + assert(results.length === 1); + assert.equal('en-US', results[0]); + }); + it('should return ["en-US"] if Accept-Language header value is "en"', () => { + let mockRequest = { headers: { 'accept-language': 'en' }}; + let results = l10n.getLanguages(mockRequest); + assert(results.length === 1); + assert.equal('en-US', results[0]); + }); + }); +});