diff --git a/node_modules/frontdoor/lib/route.js b/node_modules/frontdoor/lib/route.js index a4f3eeee..9797883c 100644 --- a/node_modules/frontdoor/lib/route.js +++ b/node_modules/frontdoor/lib/route.js @@ -195,19 +195,25 @@ module.exports = function Route(route, options, handler, types) { var type = param.type; var value = EMPTY; var isValid = true; - switch(param.source) { + switch (param.source) { case "body": if (param.optional && !(key in body)) break; value = body[key]; // body is already JSON parsed - if (param.optional && value == null) + if (param.optional && value == null) { + value = EMPTY; break; + } + isValid = type.check(value); break; + case "query": - if (param.optional && query[key] == null) + if (param.optional && query[key] == null) { + value = EMPTY; break; + } try { value = type.parse(query[key]); @@ -216,13 +222,19 @@ module.exports = function Route(route, options, handler, types) { } isValid = isValid === false ? false : type.check(value); break; + case "url": - if (param.optional && urlParams[key] == null) + if (param.optional && urlParams[key] == null) { + value = EMPTY; break; + } value = urlParams[key]; // is already parsed and checked isValid = true; break; + + default: + throw new Error("Invalid source: " + params.source); } if (!isValid) { @@ -238,7 +250,6 @@ module.exports = function Route(route, options, handler, types) { req.params[key] = value; else if ("default" in param) req.params[key] = param.default; - } } } diff --git a/node_modules/frontdoor/lib/route_test.js b/node_modules/frontdoor/lib/route_test.js index d1a1bacd..da1da6a5 100644 --- a/node_modules/frontdoor/lib/route_test.js +++ b/node_modules/frontdoor/lib/route_test.js @@ -164,6 +164,38 @@ module.exports = { }); }, + "test router: decode parameter in body with defaults": function(next) { + var route = new Route("/user", { + params: { + scm: { + type: /^(git|hg)?$/, + optional: true, + default: "git", + source: "body" + } + } + }, sinon.stub()); + + var req = { + match: "match", + parsedUrl: { query: "" }, + body: { } + }; + var res = {}; + + route.decodeParams(req, res, function(err, result) { + assert.equal(err, null); + assert.equal(req.params.scm, "git"); + + req.body.scm = null; // should be treated the same as undefined + route.decodeParams(req, res, function(err, result) { + assert.equal(err, null); + assert.equal(req.params.scm, "git"); + next(); + }); + }); + }, + "test router: optional number argument can be falsy": function(next) { var route = new Route("/user", { params: { diff --git a/package.json b/package.json index 56511491..08d40db4 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "c9", "description": "New Cloud9 Client", - "version": "3.1.760", + "version": "3.1.812", "author": "Ajax.org B.V. ", "private": true, "main": "bin/c9", diff --git a/plugins/c9.error/error_handler.js b/plugins/c9.error/error_handler.js index 3b783078..a898d16b 100644 --- a/plugins/c9.error/error_handler.js +++ b/plugins/c9.error/error_handler.js @@ -122,7 +122,7 @@ function plugin(options, imports, register) { var allowedErrorKeys = [ "message", "projectState", "premium", "retryIn", "progress", - "oldHost", "blocked", "className" + "oldHost", "blocked", "className", "errors" ]; allowedErrorKeys.forEach(function(key) { diff --git a/plugins/c9.preview/preview.js b/plugins/c9.preview/preview.js index 95f6e72c..853a33e7 100644 --- a/plugins/c9.preview/preview.js +++ b/plugins/c9.preview/preview.js @@ -6,6 +6,7 @@ define(function(require, exports, module) { "db", "c9.login", "preview.handler", + "vfs.serverlist", "user-content.redirect", "connect.remote-address" ]; @@ -13,21 +14,18 @@ define(function(require, exports, module) { return main; function main(options, imports, register) { - var maxVfsAge = options.maxVfsAge || 20 * 1000; - var region = options.region; - var session = imports.session; var db = imports.db; var ensureLoggedIn = imports["c9.login"].ensureLoggedIn(); var handler = imports["preview.handler"]; var userContent = imports["user-content.redirect"]; + var getVfsServers = imports["vfs.serverlist"].getServers; var frontdoor = require("frontdoor"); var error = require("http-error"); var requestTimeout = require("c9/request_timeout"); var api = frontdoor(); - var vfsServers; api.registerType("username", /^[0-9a-z_\-]*$/i); api.registerType("projectname", /^[0-9a-z\-_]*$/i); @@ -55,7 +53,7 @@ define(function(require, exports, module) { handler.getProjectSession(), handler.getRole(db), handler.getProxyUrl(function() { - return vfsServers ? vfsServers[0] : null; + return getVfsServers()[0] || null; }), handler.proxyCall() ]); @@ -81,53 +79,7 @@ define(function(require, exports, module) { }, function(req, res, next) { res.redirect(req.url + "/"); }); - - function updateVfsServerList(callback) { - db.Vfs.findAllAndPurge(maxVfsAge, function(err, servers) { - if (err) - return callback(err); - if (!servers.length) - return callback(new Error("No VFS server available")); - - vfsServers = shuffleServers(servers); - callback(); - }); - } - - function shuffleServers(servers) { - servers = servers.slice(); - var isBeta = region == "beta"; - servers = servers.filter(function(s) { - return isBeta ? s.region == "beta" : s.region !== "beta"; - }); - return servers.sort(function(a, b) { - if (a.region == b.region) { - if (a.load < b.load) - return -1; - else - return 1; - } - else if (a.region == region) - return -1; - else if (b.region == region) - return 1; - else - return 0; - }); - } - - load(); - function load() { - updateVfsServerList(function(err) { - if (err) - return setTimeout(load, 20000); - - setInterval(updateVfsServerList.bind(null, function(err) { - if (err) console.error("Retrieving VFS server list failed", err); - }), 20 * 1000); - - register(); - }); - } + + register(); } }); \ No newline at end of file diff --git a/plugins/c9.vfs.client/vfs.listener.js b/plugins/c9.vfs.client/vfs.listener.js index 5aae4c2f..e2a7b816 100644 --- a/plugins/c9.vfs.client/vfs.listener.js +++ b/plugins/c9.vfs.client/vfs.listener.js @@ -5,7 +5,7 @@ define(function(require, exports, module) { "use strict"; main.consumes = [ - "Plugin", "pubsub", "vfs", "metrics", "vfs.endpoint" + "Plugin", "pubsub", "vfs", "metrics", "vfs.endpoint", "dialog.alert" ]; main.provides = ["vfs.listener"]; return main; @@ -16,6 +16,7 @@ define(function(require, exports, module) { var vfs = imports.vfs; var vfsEndpoint = imports["vfs.endpoint"]; var metrics = imports.metrics; + var showAlert = imports["dialog.alert"].show; /***** Initialization *****/ @@ -35,6 +36,20 @@ define(function(require, exports, module) { vfsEndpoint.clearCache(); vfs.reconnect(); } + else if (m.action == "remote_changed") { + metrics.increment("vfs.remote_changed", 1, true); + vfsEndpoint.clearCache(); + + showAlert("Workspace configuration changed!", + "The configuration of this workspace has changed.", + "Cloud9 will be reloaded in order to activate the changes.", + function() { + setTimeout(function() { + window.location.reload(); + }, 500); + } + ); + } }); } diff --git a/scripts/makestatic.js b/scripts/makestatic.js index 2ccaabe9..92238a73 100755 --- a/scripts/makestatic.js +++ b/scripts/makestatic.js @@ -76,7 +76,7 @@ function main(config, settings, options, callback) { }) .concat({ consumes: [], - provides: ["cdn.build", "db", "health"], + provides: ["cdn.build", "db", "redis", "health"], setup: function(options, imports, register) { register(null, { "cdn.build": {}, @@ -87,6 +87,7 @@ function main(config, settings, options, callback) { } } }, + "redis": {}, "health": { addCheck: function() {} }