diff --git a/index.js b/index.js index 6b12b69..0616729 100644 --- a/index.js +++ b/index.js @@ -30,6 +30,10 @@ FileList = cdnSync.FileList; var localFiles; +// lift the default socket cap from 5 to Infinity +require('http').globalAgent.maxSockets = Infinity; +require('https').globalAgent.maxSockets = Infinity; + function init(options) { var target = path.join(process.cwd(), '.cdn-sync.json'); if (options.force) { diff --git a/lib/cdn/aws.js b/lib/cdn/aws.js index 7e058b2..a5f0918 100644 --- a/lib/cdn/aws.js +++ b/lib/cdn/aws.js @@ -175,7 +175,7 @@ CDN.prototype.executeActions = function (actions, options) { * @param {File} file */ CDN.prototype.fixFile = function (file) { - var self, dfrd, options; + var self, dfrd, options, timer; self = this; dfrd = Q.defer(); @@ -185,22 +185,35 @@ CDN.prototype.fixFile = function (file) { return dfrd.promise; } + timer = setTimeout(function () { + var error; + error = new Error('fixFile took too long: ' + file.path); + console.error(error); + dfrd.reject(error); + }, 15 * 1e3); // wait 15 seconds + options = { Bucket: this.cfg.Bucket, Key: file.path }; this.api.headObject(options, function (err, res) { - if (err) { - console.error(err); - dfrd.reject(err); - return; - } - file.setMIME(res.ContentType); - if (res.ContentEncoding) { - file.headers['Content-Encoding'] = res.ContentEncoding; + try { + if (err) { + console.error(err); + dfrd.reject(err); + return; + } + file.setMIME(res.ContentType); + if (res.ContentEncoding) { + file.headers['Content-Encoding'] = res.ContentEncoding; + } + self.emit('file:fixed'); + dfrd.resolve(); + } catch (e) { + console.error(e); + dfrd.reject(e); } - self.emit('file:fixed'); - dfrd.resolve(); + clearTimeout(timer); }); // TODO: check cache headers and permissions diff --git a/lib/config.js b/lib/config.js index dda62cb..dca75de 100644 --- a/lib/config.js +++ b/lib/config.js @@ -38,18 +38,16 @@ Config.validate = function (obj) { dfrd = Q.defer(); validator = new ZSchema(); - validator.validate(obj, schema, function (err, report) { - var error; - if (err) { - dfrd.reject(err); + validator.validate(obj, schema, function (err, valid) { + if (!valid || err) { + if (Array.isArray(err) && err.length) { + dfrd.reject(err[0]); + } else { + dfrd.reject(err); + } return; } - if (!report || report.valid) { - dfrd.resolve(); - } else { - error = report.errors[0]; - dfrd.reject(new TypeError(error.path + ': ' + error.message)); - } + dfrd.resolve(); }); return dfrd.promise; }; diff --git a/package.json b/package.json index 1fe838b..4869385 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "cdn-sync", "description": "deflate / synchronise assets to a CDN", - "version": "0.5.0", + "version": "0.6.0", "homepage": "https://github.com/jokeyrhyme/cdn-sync", "author": { "name": "Ron Waldon", @@ -37,26 +37,27 @@ }, "dependencies": { "async": "0.9.0", - "aws-sdk": "2.0.6", - "cli": "0.6.3", + "aws-sdk": "2.0.15", + "cli": "0.6.4", "findup-sync": "0.1.3", - "glob": "4.0.3", + "glob": "4.0.5", "graceful-fs": "3.0.2", "mime": "1.2.11", "mmmagic": "0.3.8", "progress": "~1.1.7", "q": "0.9.7", - "underscore": "1.6.0", - "z-schema": "2.4.8" + "underscore": "1.7.0", + "z-schema": "3.0.0" }, "devDependencies": { "chai": "~1.9", "grunt": "~0.4", "grunt-contrib-watch": "~0.6", "grunt-jslint": "~1.1", - "grunt-mocha-cli": "~1.9", - "grunt-mocha-cov": "~0.2", - "mocha": "~1.20", + "grunt-mocha-cli": "~1.10", + "grunt-mocha-cov": "~0.3", + "mocha": "~1.21", + "request": "^2.40.0", "sinon": "~1.10", "sinon-chai": "~2.5" }, diff --git a/test/json_schema_test.js b/test/json_schema_test.js index 60c168d..e6fdfd1 100644 --- a/test/json_schema_test.js +++ b/test/json_schema_test.js @@ -9,11 +9,12 @@ path = require('path'); // 3rd-party modules -var chai, assert, sinon, ZSchema; +var chai, assert, sinon, request, ZSchema; chai = require('chai'); chai.use(require('sinon-chai')); assert = require('chai').assert; +request = require('request'); sinon = require('sinon'); ZSchema = require('z-schema'); @@ -41,37 +42,40 @@ example = { }; suite('JSON schema for `.cdn-sync.json`', function () { - var validator, schema, compiledSchema; + var validator, schema, jsonSchemaURL; - suiteSetup(function () { + suiteSetup(function (done) { + jsonSchemaURL = 'http://json-schema.org/draft-04/schema'; validator = new ZSchema({ - strict: false // true + strictMode: false // true }); schema = require(path.join(__dirname, '..', 'doc', 'cdn-sync.schema.json')); - }); - - test('schema passes validation', function (done) { - validator.validateSchema(schema, function (err, report) { - assert.isNull(err); - assert.isObject(report); - assert.lengthOf(report.errors, 0); + request(jsonSchemaURL, function (err, res, body) { + validator.setRemoteReference(jsonSchemaURL, JSON.parse(body)); done(); }); }); - test('schema compiles', function (done) { - validator.compileSchema(schema, function (err, compiled) { - assert(true, 'asynchronous callback is executed'); - assert.isNull(err, 'no compilation errors'); - assert(compiled); - compiledSchema = compiled; - done(); - }); + test('schema passes validation', function () { + var err, valid; + valid = validator.validateSchema(schema); + err = validator.getLastErrors(); + assert(!err); + assert.isTrue(valid); + }); + + test('schema compiles', function () { + var err, valid; + valid = validator.compileSchema(schema); + err = validator.getLastErrors(); + assert(!err); + assert.isTrue(valid); }); test('example validates against compiled schema', function (done) { - validator.validate(example, compiledSchema, function (report) { - assert.isNull(report); + validator.validate(example, schema, function (err, valid) { + assert(!err); + assert.isTrue(valid); done(); }); }); @@ -80,8 +84,9 @@ suite('JSON schema for `.cdn-sync.json`', function () { var broken; broken = JSON.parse(JSON.stringify(example)); delete broken.targets[0].options.region; - validator.validate(broken, compiledSchema, function (err, report) { - assert.isObject(err); + validator.validate(broken, schema, function (err, valid) { + assert(err); + assert.isFalse(valid); done(); }); });