var url = require('url'),
fs = require('fs'),
node_static = require('node-static'),
- _ = require('lodash');
+ Negotiator = require('negotiator'),
+ _ = require('lodash'),
+ config = require('./configuration.js'),
+ SettingsGenerator = require('./settingsgenerator.js');
+
var HttpHandler = function (config) {
- var public_html = config.public_html || 'client/';
- this.file_server = new node_static.Server(public_html);
+ var public_http = config.public_http || 'client/';
+ this.file_server = new node_static.Server(public_http);
};
module.exports.HttpHandler = HttpHandler;
// Any asset request to head into the asset dir
request.url = request.url.replace(base_path + '/assets/', '/assets/');
+ // Any src request to head into the src dir
+ request.url = request.url.replace(base_path + '/src/', '/src/');
+
// Any requests for /client to load the index file
if (request.url.match(new RegExp('^' + base_path_regex + '([/$]|$)', 'i'))) {
- request.url = '/';
+ request.url = '/index.html';
}
// If the 'magic' translation is requested, figure out the best language to use from
} else {
response.setHeader('Content-Language', request.url.substr(16, request.url.indexOf('.') - 16));
}
+ } else if (request.url.substr(0, 21) === '/assets/settings.json') {
+ return serveSettings.call(this, request, response);
}
this.file_server.serve(request, response, function (err) {
});
};
+
+// 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;
-
- if (request.headers['accept-language']) {
- 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
-
- // 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])) {
- return that.file_server.serveFile('/assets/locales/' + langs[i][0] + '.json', 200, {Vary: 'Accept-Language', 'Content-Language': langs[i][0]}, request, response);
- }
- }
-
- serveFallbackLocale.call(that, request, response);
- });
+ 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
+ found_locale = default_locale_id;
+
} else {
- serveFallbackLocale.call(that, request, response);
+ negotiator = new Negotiator(request);
+ found_locale = negotiator.language(cached_available_locales);
}
+
+ // Send a locale to the browser
+ this.file_server.serveFile('/assets/locales/' + found_locale + '.json', 200, {
+ Vary: 'Accept-Language',
+ 'Content-Language': found_locale
+ }, request, response);
};
-var serveFallbackLocale = function (request, response) {
- //en-gb is our default language, so we serve this as the last possible answer for everything
- this.file_server.serveFile('/assets/locales/en-gb.json', 200, {Vary: 'Accept-Language', 'Content-Language': 'en-gb'}, request, response);
+
+
+/**
+ * Handle the settings.json request
+ */
+var serveSettings = function(request, response) {
+ var referrer_url,
+ debug = false,
+ settings;
+
+ // Check the referrer for a debug option
+ if (request.headers['referer']) {
+ referrer_url = url.parse(request.headers['referer'], true);
+ if (referrer_url.query && referrer_url.query.debug) {
+ debug = true;
+ }
+ }
+
+ SettingsGenerator.get(debug, function(settings) {
+ if (request.headers['if-none-match'] && request.headers['if-none-match'] === settings.hash) {
+ response.writeHead(304, 'Not Modified');
+ return response.end();
+ }
+
+ response.writeHead(200, {
+ 'ETag': settings.hash,
+ 'Content-Type': 'application/json'
+ });
+ response.end(settings.settings);
+ });
};