diff --git a/index.js b/index.js index b28ecfb0..a943ec8e 100644 --- a/index.js +++ b/index.js @@ -6,6 +6,7 @@ var url = require('url'); var async = require("async"); var util = require("./util/util"); +var legacy = require("./util/legacy"); var http = require('http'); var https = require('https'); @@ -116,9 +117,9 @@ exports = module.exports = function() // if there is a "gitana.json" file in the app server base path, we load proxy settings from there if they're // not already specified - var defaultGitanaProxyHost = "api.cloudcms.com"; - var defaultGitanaProxyPort = 443; - var defaultGitanaProxyScheme = "https"; + var defaultGitanaProxyScheme = legacy.DEFAULT_GITANA_PROXY_SCHEME; + var defaultGitanaProxyHost = legacy.DEFAULT_GITANA_PROXY_HOST; + var defaultGitanaProxyPort = legacy.DEFAULT_GITANA_PROXY_PORT; var gitanaJsonPath = path.join(process.env.CLOUDCMS_APPSERVER_BASE_PATH, "gitana.json"); if (fs.existsSync(gitanaJsonPath)) @@ -157,7 +158,10 @@ exports = module.exports = function() process.env.GITANA_PROXY_PORT = defaultGitanaProxyPort; } - console.log("Gitana Proxy pointed to: " + process.env.GITANA_PROXY_SCHEME + "://" + process.env.GITANA_PROXY_HOST + ":" + process.env.GITANA_PROXY_PORT); + // auto-upgrade usage of "api.cloudcms.com" to "api1.cloudcms.com" + process.env.GITANA_PROXY_HOST = legacy.autoUpgrade(process.env.GITANA_PROXY_HOST, true); + + console.log("Gitana Proxy pointed to: " + util.asURL(process.env.GITANA_PROXY_SCHEME, process.env.GITANA_PROXY_HOST, process.env.GITANA_PROXY_PORT)); // all web modules are included by default if (!process.includeWebModule) { diff --git a/insight/insight.js b/insight/insight.js index 74067943..93239c4f 100644 --- a/insight/insight.js +++ b/insight/insight.js @@ -131,7 +131,7 @@ var doSend = function(callback) } // url over to cloud cms - var URL = process.env.GITANA_PROXY_SCHEME + "://" + process.env.GITANA_PROXY_HOST + ":" + process.env.GITANA_PROXY_PORT + "/warehouses/" + warehouseId + "/interactions/_create"; + var URL = util.asURL(process.env.GITANA_PROXY_SCHEME, process.env.GITANA_PROXY_HOST, process.env.GITANA_PROXY_PORT) + "/warehouses/" + warehouseId + "/interactions/_create"; var requestConfig = { "url": URL, "qs": {}, diff --git a/middleware/form/form.js b/middleware/form/form.js index 1dddc310..2104ff8c 100644 --- a/middleware/form/form.js +++ b/middleware/form/form.js @@ -121,7 +121,7 @@ exports = module.exports = function() } // post form to Cloud CMS using public method - var URL = process.env.GITANA_PROXY_SCHEME + "://" + process.env.GITANA_PROXY_HOST + ":" + process.env.GITANA_PROXY_PORT + url; + var URL = util.asURL(process.env.GITANA_PROXY_SCHEME, process.env.GITANA_PROXY_HOST, process.env.GITANA_PROXY_PORT) + url; var headers = {}; headers["Authorization"] = req.gitana.platform().getDriver().getHttpHeaders()["Authorization"]; @@ -192,7 +192,7 @@ exports = module.exports = function() var url = branch.getUri() + "/alpaca/datasource"; - var URL = process.env.GITANA_PROXY_SCHEME + "://" + process.env.GITANA_PROXY_HOST + ":" + process.env.GITANA_PROXY_PORT + url; + var URL = util.asURL(process.env.GITANA_PROXY_SCHEME, process.env.GITANA_PROXY_HOST, process.env.GITANA_PROXY_PORT) + url; var headers = {}; headers["Authorization"] = req.gitana.platform().getDriver().getHttpHeaders()["Authorization"]; diff --git a/middleware/proxy/proxy.js b/middleware/proxy/proxy.js index 77f5c81d..4e80f058 100644 --- a/middleware/proxy/proxy.js +++ b/middleware/proxy/proxy.js @@ -32,10 +32,10 @@ var util = require("../../util/util"); */ exports = module.exports = function() { - var MAXAGE_ONE_YEAR_SECONDS = 31536000; - var MAXAGE_ONE_HOUR_SECONDS = 3600; - var MAXAGE_ONE_WEEK_SECONDS = 604800; - var MAXAGE_ONE_MONTH_SECONDS = 2592000; + //var MAXAGE_ONE_YEAR_SECONDS = 31536000; + //var MAXAGE_ONE_HOUR_SECONDS = 3600; + //var MAXAGE_ONE_WEEK_SECONDS = 604800; + //var MAXAGE_ONE_MONTH_SECONDS = 2592000; var _cacheTTL = function(req) { @@ -267,8 +267,8 @@ exports = module.exports = function() "target": target, "agent": http.globalAgent, "xfwd": false, - "proxyTimeout": process.defaultHttpTimeoutMs, - "changeOrigin": changeOrigin + "proxyTimeout": process.defaultHttpTimeoutMs//, + //"changeOrigin": changeOrigin }; // use https? @@ -375,6 +375,8 @@ exports = module.exports = function() req.headers["x-cloudcms-origin"] = cloudcmsOrigin; } + // set x-cloudcms-server-version header + req.headers["x-cloudcms-server-version"] = process.env.CLOUDCMS_APPSERVER_PACKAGE_VERSION; // determine the domain to set the "host" header on the proxied call // this is what we pass to the API server diff --git a/middleware/virtual-config/virtual-config.js b/middleware/virtual-config/virtual-config.js index 60b19dc3..50b8c5a8 100644 --- a/middleware/virtual-config/virtual-config.js +++ b/middleware/virtual-config/virtual-config.js @@ -2,6 +2,7 @@ var path = require('path'); var http = require('http'); var request = require('request'); var util = require("../../util/util"); +var legacy = require("../../util/legacy"); /** * Retrieves virtual driver configuration for hosts from Cloud CMS. @@ -65,7 +66,7 @@ exports = module.exports = function() { uri += "/" + configuration.virtualDriver.appKey; } - var URL = process.env.GITANA_PROXY_SCHEME + "://" + process.env.GITANA_PROXY_HOST + ":" + process.env.GITANA_PROXY_PORT + "/virtual/driver/config"; + var URL = util.asURL(process.env.GITANA_PROXY_SCHEME, process.env.GITANA_PROXY_HOST, process.env.GITANA_PROXY_PORT) + "/virtual/driver/config"; var qs = { "uri": uri }; @@ -188,8 +189,7 @@ exports = module.exports = function() if (virtualConfig.application) { gitanaJson.application = virtualConfig.application; } - var URL = process.env.GITANA_PROXY_SCHEME + "://" + process.env.GITANA_PROXY_HOST + ":" + process.env.GITANA_PROXY_PORT; - gitanaJson.baseURL = URL; + gitanaJson.baseURL = util.asURL(process.env.GITANA_PROXY_SCHEME, process.env.GITANA_PROXY_HOST, process.env.GITANA_PROXY_PORT); // mark as retrieved from virtual driver gitanaJson._virtual = true; @@ -245,6 +245,23 @@ exports = module.exports = function() */ } + // auto-upgrade the host? + if (gitanaJson.baseURL) + { + var newBaseURL = legacy.autoUpgrade(gitanaJson.baseURL, true); + if (newBaseURL !== gitanaJson.baseURL) + { + gitanaJson.baseURL = legacy.autoUpgrade(gitanaJson.baseURL, true); + gitanaJson.baseURL = util.cleanupURL(gitanaJson.baseURL); + + // write the gitana.json file + rootStore.writeFile("gitana.json", JSON.stringify(gitanaJson, null, " "), function (err) { + // nada + }); + } + + } + // otherwise, fine! callback(null, gitanaJson); @@ -270,7 +287,7 @@ exports = module.exports = function() // defaults if (!configuration.baseURL) { - configuration.baseURL = process.env.GITANA_PROXY_SCHEME + "://" + process.env.GITANA_PROXY_HOST + ":" + process.env.GITANA_PROXY_PORT; + configuration.baseURL = util.asURL(process.env.GITANA_PROXY_SCHEME, process.env.GITANA_PROXY_HOST, process.env.GITANA_PROXY_PORT); } if (!configuration.key) { configuration.key = "virtual"; diff --git a/package.json b/package.json index cc6da377..d5c1657c 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ }, "name": "cloudcms-server", "description": "Cloud CMS Application Server Module", - "version": "0.8.412", + "version": "0.8.413", "repository": { "type": "git", "url": "git://github.com/gitana/cloudcms-server.git" @@ -35,7 +35,7 @@ "express": "^4.15.2", "express-session": "^1.14.1", "express-useragent": "^1.0.4", - "gitana": "^1.0.242", + "gitana": "^1.0.244", "handlebars": "^4.0.5", "hbs": "^4.0.1", "http-proxy": "^1.16.2", diff --git a/util/auth.js b/util/auth.js index 52703563..0c4108e2 100644 --- a/util/auth.js +++ b/util/auth.js @@ -439,7 +439,7 @@ var impersonate = exports.impersonate = function(req, key, targetUser, callback) agent = https.globalAgent; } - var baseURL = process.env.GITANA_PROXY_SCHEME + "://" + process.env.GITANA_PROXY_HOST + ":" + process.env.GITANA_PROXY_PORT; + var baseURL = util.asURL(process.env.GITANA_PROXY_SCHEME, process.env.GITANA_PROXY_HOST, process.env.GITANA_PROXY_PORT); request({ "method": "POST", diff --git a/util/cloudcms.js b/util/cloudcms.js index ffe6dcc6..8a64a117 100644 --- a/util/cloudcms.js +++ b/util/cloudcms.js @@ -369,7 +369,7 @@ exports = module.exports = function() agent = https.globalAgent; } - var URL = process.env.GITANA_PROXY_SCHEME + "://" + process.env.GITANA_PROXY_HOST + ":" + process.env.GITANA_PROXY_PORT + uri; + var URL = util.asURL(process.env.GITANA_PROXY_SCHEME, process.env.GITANA_PROXY_HOST, process.env.GITANA_PROXY_PORT) + uri; request({ "method": "GET", "url": URL, diff --git a/util/legacy.js b/util/legacy.js new file mode 100644 index 00000000..286533b3 --- /dev/null +++ b/util/legacy.js @@ -0,0 +1,57 @@ +var exports = module.exports; + +exports.DEFAULT_GITANA_PROXY_SCHEME = "https"; +exports.DEFAULT_GITANA_PROXY_HOST = "api1.cloudcms.com"; +exports.DEFAULT_GITANA_PROXY_PORT = 443; + +/** + * This version of the cloudcms-server supports CloudFront CDN. Anybody using "api.cloudcms.com" can auto-upgrade + * to "api1.cloudcms.com" for the time being as this points to CloudFront. + * + * In the future, we'll migrate "api.cloudcms.com" to CloudFront and this will no longer be necessary. + * + * @param host + * @returns {*} + */ +exports.autoUpgrade = function(hostOrUrl, verbose) +{ + // default value if not supplied + if (typeof(process.env.CLOUDCMS_API_PREFER_CDN) === "undefined") { + process.env.CLOUDCMS_API_PREFER_CDN = "true"; + process.env.CLOUDCMS_API_PREFER_LB = "false"; + } + + if (hostOrUrl) + { + var handleReplaceHost = function(hostOrUrl, oldHost, newHost, verbose, loggerFn) + { + if (hostOrUrl.indexOf(oldHost) > -1) + { + if (verbose) + { + loggerFn(oldHost, newHost); + } + + hostOrUrl = hostOrUrl.replace(oldHost, newHost); + } + + return hostOrUrl; + }; + + if (process.env.CLOUDCMS_API_PREFER_CDN === true || process.env.CLOUDCMS_API_PREFER_CDN === "true") + { + hostOrUrl = handleReplaceHost(hostOrUrl, "api.cloudcms.com", "api1.cloudcms.com", verbose, function(oldHost, newHost) { + console.log("Adjusting API connection to use CloudFront: " + oldHost + " to: " + newHost + " for improved edge performance"); + }); + } + else if (process.env.CLOUDCMS_API_PREFER_LB === true || process.env.CLOUDCMS_API_PREFER_LB === "true") + { + hostOrUrl = handleReplaceHost(hostOrUrl, "api1.cloudcms.com", "api.cloudcms.com", verbose, function(oldHost, newHost) { + console.log("Adjusting API connection to use Load Balancer: " + oldHost + " to: " + newHost); + }); + + } + } + + return hostOrUrl; +}; \ No newline at end of file diff --git a/util/renditions.js b/util/renditions.js index 6e2bcb96..da9a4086 100644 --- a/util/renditions.js +++ b/util/renditions.js @@ -166,7 +166,7 @@ exports = module.exports = function() //console.log("PAGE RENDITION OBJECT"); //console.log(JSON.stringify(renditionObject, null, " ")); - var URL = process.env.GITANA_PROXY_SCHEME + "://" + process.env.GITANA_PROXY_HOST + ":" + process.env.GITANA_PROXY_PORT + "/applications/" + applicationId + "/deployments/" + deploymentKey + "/pagerenditions"; + var URL = util.asURL(process.env.GITANA_PROXY_SCHEME, process.env.GITANA_PROXY_HOST, process.env.GITANA_PROXY_PORT) + "/applications/" + applicationId + "/deployments/" + deploymentKey + "/pagerenditions"; //console.log("URL: " + URL); //console.log("Mark Rendition: " + JSON.stringify(renditionObject, null, " ")); diff --git a/util/util.js b/util/util.js index 7373cfa5..89257f3a 100644 --- a/util/util.js +++ b/util/util.js @@ -16,6 +16,8 @@ var archiver = require("archiver"); var http = require("http"); var https = require("https"); +var urlTool = require("url"); + var VALID_IP_ADDRESS_REGEX_STRING = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"; exports = module.exports; @@ -1661,3 +1663,42 @@ var zip = exports.zip = function(directoryPath, writableStream) archive.finalize(); }; +var asURL = exports.asURL = function(protocol, host, port) +{ + // make sure port is a number + if (typeof(port) === "string") { + port = parseInt(port, 10); + } + + // protocol lower case + protocol = protocol.toLowerCase(); + + var url = protocol + "://" + host; + + // if port and default port don't match, then append + if (protocol === "https" && port !== 443) + { + url += ":" + port; + } + else if (protocol === "http" && port !== 80) + { + url += ":" + port; + } + + return url; +}; + +var cleanupURL = exports.cleanupURL = function(url) +{ + var _url = urlTool.parse(url); + + // if protocol is "https:" (for example), strip back to "https" + var protocol = _url.protocol; + var a = protocol.indexOf(":"); + if (a > -1) + { + protocol = protocol.substring(0, a); + } + + return asURL(protocol, _url.hostname, _url.port); +};