Commit | Line | Data |
---|---|---|
bd299b17 | 1 | var url = require('url'), |
0fa2ca42 JA |
2 | fs = require('fs'), |
3 | node_static = require('node-static'), | |
4 | _ = require('lodash'); | |
a8bf3ea4 | 5 | |
a8bf3ea4 | 6 | |
a8bf3ea4 | 7 | |
186531ed D |
8 | var HttpHandler = function (config) { |
9 | var public_html = config.public_html || 'client/'; | |
10 | this.file_server = new node_static.Server(public_html); | |
a8bf3ea4 JA |
11 | }; |
12 | ||
186531ed D |
13 | module.exports.HttpHandler = HttpHandler; |
14 | ||
15 | ||
16 | ||
17 | HttpHandler.prototype.serve = function (request, response) { | |
b65ad8f1 | 18 | // The incoming requests base path (ie. /kiwiclient) |
b737610b | 19 | var base_path = global.config.http_base_path || '/kiwi', |
b65ad8f1 D |
20 | base_path_regex; |
21 | ||
22 | // Trim of any trailing slashes | |
23 | if (base_path.substr(base_path.length - 1) === '/') { | |
24 | base_path = base_path.substr(0, base_path.length - 1); | |
25 | } | |
0fa2ca42 | 26 | |
b65ad8f1 D |
27 | // Build the regex to match the base_path |
28 | base_path_regex = base_path.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&'); | |
0ae87edb D |
29 | |
30 | // Any asset request to head into the asset dir | |
b65ad8f1 | 31 | request.url = request.url.replace(base_path + '/assets/', '/assets/'); |
0ae87edb | 32 | |
b075a0d6 | 33 | // Any requests for /client to load the index file |
b65ad8f1 | 34 | if (request.url.match(new RegExp('^' + base_path_regex + '([/$]|$)', 'i'))) { |
b075a0d6 D |
35 | request.url = '/'; |
36 | } | |
37 | ||
0fa2ca42 | 38 | // If the 'magic' translation is requested, figure out the best language to use from |
b722f3c6 | 39 | // the Accept-Language HTTP header. If nothing is suitible, fallback to our en-gb default translation |
28cde487 JA |
40 | if (request.url.substr(0, 16) === '/assets/locales/') { |
41 | if (request.url === '/assets/locales/magic.json') { | |
42 | return serveMagicLocale.call(this, request, response); | |
43 | } else { | |
44 | response.setHeader('Content-Language', request.url.substr(16, request.url.indexOf('.') - 16)); | |
45 | } | |
0fa2ca42 | 46 | } |
0ae87edb | 47 | |
186531ed | 48 | this.file_server.serve(request, response, function (err) { |
a8bf3ea4 | 49 | if (err) { |
bd299b17 JA |
50 | response.writeHead(err.status, err.headers); |
51 | response.end(); | |
a8bf3ea4 JA |
52 | } |
53 | }); | |
0fa2ca42 JA |
54 | }; |
55 | ||
56 | var serveMagicLocale = function (request, response) { | |
cbc8feae | 57 | var that = this; |
8e1ab29d | 58 | |
0fa2ca42 | 59 | if (request.headers['accept-language']) { |
28cde487 JA |
60 | fs.readdir('client/assets/locales', function (err, files) { |
61 | var available = [], | |
62 | i = 0, | |
cbc8feae | 63 | langs = request.headers['accept-language'].split(','); // Example: en-gb,en;q=0.5 |
28cde487 | 64 | |
8e1ab29d | 65 | // Get a list of the available translations we have |
0fa2ca42 | 66 | files.forEach(function (file) { |
28cde487 JA |
67 | if (file.substr(-5) === '.json') { |
68 | available.push(file.slice(0, -5)); | |
0fa2ca42 JA |
69 | } |
70 | }); | |
0fa2ca42 | 71 | |
8e1ab29d | 72 | // Sanitise the browsers accepted languages and the qualities |
28cde487 JA |
73 | for (i = 0; i < langs.length; i++) { |
74 | langs[i]= langs[i].split(';q='); | |
8e1ab29d | 75 | langs[i][0] = langs[i][0].toLowerCase(); |
28cde487 | 76 | langs[i][1] = (typeof langs[i][1] === 'string') ? parseFloat(langs[i][1]) : 1.0; |
0fa2ca42 | 77 | } |
8e1ab29d D |
78 | |
79 | // Sort the accepted languages by quality | |
28cde487 JA |
80 | langs.sort(function (a, b) { |
81 | return b[1] - a[1]; | |
82 | }); | |
8e1ab29d D |
83 | |
84 | // Serve the first language we have a translation for | |
28cde487 JA |
85 | for (i = 0; i < langs.length; i++) { |
86 | if (langs[i][0] === '*') { | |
87 | break; | |
88 | } else if (_.contains(available, langs[i][0])) { | |
cbc8feae | 89 | return that.file_server.serveFile('/assets/locales/' + langs[i][0] + '.json', 200, {Vary: 'Accept-Language', 'Content-Language': langs[i][0]}, request, response); |
28cde487 JA |
90 | } |
91 | } | |
8e1ab29d D |
92 | |
93 | serveFallbackLocale.call(that, request, response); | |
28cde487 | 94 | }); |
d2831ddd | 95 | } else { |
8e1ab29d | 96 | serveFallbackLocale.call(that, request, response); |
0fa2ca42 | 97 | } |
d2831ddd | 98 | }; |
cbc8feae | 99 | |
d2831ddd | 100 | var serveFallbackLocale = function (request, response) { |
b722f3c6 | 101 | //en-gb is our default language, so we serve this as the last possible answer for everything |
d2831ddd | 102 | this.file_server.serveFile('/assets/locales/en-gb.json', 200, {Vary: 'Accept-Language', 'Content-Language': 'en-gb'}, request, response); |
0fa2ca42 | 103 | }; |