var dot = require('dot'); dot.templateSettings.strip = false; function ResourceLocator(environment) { this.environment = environment; this.resourcesUrlTemplates = null; if (this.environment.resources_url_templates) { var templates = environment.resources_url_templates; if (templates.http) { this.resourcesUrlTemplates = this.resourcesUrlTemplates || {}; this.resourcesUrlTemplates.http = dot.template(templates.http + '/{{=it.resource}}'); } if (templates.https) { this.resourcesUrlTemplates = this.resourcesUrlTemplates || {}; this.resourcesUrlTemplates.https = dot.template(templates.https + '/{{=it.resource}}'); } } } module.exports = ResourceLocator; ResourceLocator.prototype.getUrls = function(username, resource) { if (this.resourcesUrlTemplates) { return this.getUrlsFromTemplate(username, resource); } var cdnDomain = getCdnDomain(this.environment.serverMetadata, resource); if (cdnDomain) { return { http: 'http://' + cdnDomain.http + '/' + username + '/api/v1/map/' + resource, https: 'https://' + cdnDomain.https + '/' + username + '/api/v1/map/' + resource }; } else { var port = this.environment.port; return { http: 'http://' + username + '.' + 'localhost.lan:' + port + '/api/v1/map/' + resource }; } }; ResourceLocator.prototype.getUrlsFromTemplate = function(username, resource) { var urls = {}; var cdnDomain = getCdnDomain(this.environment.serverMetadata, resource) || {}; if (this.resourcesUrlTemplates.http) { urls.http = this.resourcesUrlTemplates.http({ cdn_url: cdnDomain.http, user: username, port: this.environment.port, resource: resource }); } if (this.resourcesUrlTemplates.https) { urls.https = this.resourcesUrlTemplates.https({ cdn_url: cdnDomain.https, user: username, port: this.environment.port, resource: resource }); } return urls; }; function getCdnDomain(serverMetadata, resource) { if (serverMetadata && serverMetadata.cdn_url) { var cdnUrl = serverMetadata.cdn_url; var http = cdnUrl.http; var https = cdnUrl.https; if (cdnUrl.templates) { var templates = cdnUrl.templates; var httpUrlTemplate = templates.http.url; var httpsUrlTemplate = templates.https.url; http = httpUrlTemplate .replace(/^(http[s]*:\/\/)/, '') .replace('{s}', subdomain(templates.http.subdomains, resource)); https = httpsUrlTemplate .replace(/^(http[s]*:\/\/)/, '') .replace('{s}', subdomain(templates.https.subdomains, resource)); } return { http: http, https: https, }; } return null; } // ref https://jsperf.com/js-crc32 function crcTable() { var c; var table = []; for (var n = 0; n < 256; n++) { c = n; for (var k = 0; k < 8; k++) { c = ((c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1)); } table[n] = c; } return table; } var CRC_TABLE = crcTable(); function crc32(str) { var crc = 0 ^ (-1); for (var i = 0; i < str.length; i++) { crc = (crc >>> 8) ^ CRC_TABLE[(crc ^ str.charCodeAt(i)) & 0xFF]; } return (crc ^ (-1)) >>> 0; } function subdomain(subdomains, resource) { var index = crc32(resource) % subdomains.length; return subdomains[index]; } module.exports.subdomain = subdomain;