Skip to content

Commit

Permalink
Merge pull request #83 from prey/1.3.7-rc2
Browse files Browse the repository at this point in the history
1.3.7-rc2
  • Loading branch information
mauricioschneider committed Mar 11, 2015
2 parents 9280ffc + 5f06463 commit 3da96ce
Show file tree
Hide file tree
Showing 14 changed files with 1,213 additions and 377 deletions.
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.10.32
0.10.36
81 changes: 54 additions & 27 deletions lib/agent/plugins/control-panel/api/request.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,29 @@ var needle = require('needle'),
version = '2';

var defaults = {
client : needle,
protocol : 'https',
host : 'solid.preyproject.com',
user_agent : 'Prey Client API v' + version,
timeout : 90 * 1000
}
client : needle,
protocol : 'https',
host : 'solid.preyproject.com',
user_agent : 'Prey Client API v' + version,
timeout : 90 * 1000,
retry_timeout : 3 * 1000,
try_proxy : ''
};

https.globalAgent.options.secureProtocol = 'TLSv1_method';

var api_root = '/api/v2';
var max_attempts = 3;
var api_root = '/api/v2',
max_attempts = 3;

var is_network_down = function(err) {
var codes = ['ENETDOWN', 'ENETUNREACH', 'EADDRINFO', 'ENOTFOUND'];
var codes = ['ENETDOWN', 'ENETUNREACH', 'EADDRINFO', 'ENOTFOUND', 'EHOSTUNREACH'];
return codes.indexOf(err.code) !== -1;
}
};

var is_server_down = function(err) {
var codes = ['ETIMEDOUT', 'ECONNRESET', 'ECONNREFUSED'];
return codes.indexOf(err.code) !== -1;
}
};

var is_temporary_error = function(err, resp) {
var retry = false;
Expand All @@ -36,12 +38,15 @@ var is_temporary_error = function(err, resp) {
retry = (resp.statusCode == 502 || resp.statusCode == 503);

return retry;
}
};

var send = function(attempt, method, path, data, options, cb) {
if (!defaults.client)
return cb(new Error('No HTTP client set!'))
if (!defaults.client) {
return cb(new Error('No HTTP client set!'));
}

// opts are used for the current request, while options are
// used in the recursive call in case of retry
var opts = options || {};
opts.timeout = opts.timeout || defaults.timeout;
opts.user_agent = opts.user_agent || defaults.user_agent;
Expand All @@ -53,18 +58,30 @@ var send = function(attempt, method, path, data, options, cb) {

var base = defaults.protocol + '://' + defaults.host,
url = base + api_root + path,
start = new Date();
start = new Date(),
logger_msg;

logger.debug('Sending ' + method + ' request #' + attempt + ' to ' + base);
// console.log(opts);
logger_msg = 'Sending ' + method + ' request #' + attempt + ' to ' + base;
if (opts.proxy) {
logger_msg += " using proxy: " + opts.proxy;
}
logger.debug(logger_msg);

defaults.client.request(method, url, data, opts, function(err, resp, body) {
var seconds = (new Date() - start) / 1000;
var seconds = (new Date() - start) / 1000,
retry_without_proxy = function() {
delete options.proxy;
logger.debug('Retrying request without proxy.');
send(1, method, path, data, options, cb);
};
logger.debug('Attempt #' + attempt + ' took ' + seconds + ' seconds.');

if (err && is_network_down(err)) {

err.message = 'Network seems to be down. Check your connection and try again.';
if(opts.proxy) {
return retry_without_proxy();
}
return cb(err);

} else if (is_temporary_error(err, resp)) {
Expand All @@ -73,7 +90,9 @@ var send = function(attempt, method, path, data, options, cb) {
logger.debug('Temporary network error. Retrying...');
return setTimeout(function() {
send(attempt + 1, method, path, data, options, cb);
}, 3000);
}, defaults.retry_timeout);
} else if (opts.proxy) {
return retry_without_proxy();
} else if (err) { // maxed out all attempts. tell user to retry in a sec.
err.message = err.message + ' - Please try again in a minute.';
}
Expand All @@ -82,19 +101,27 @@ var send = function(attempt, method, path, data, options, cb) {

cb(err, resp, body);
});
}
};

var set_proxy_and_send = function (method, path, data, opts, cb) {
if (!opts.hasOwnProperty("proxy") && defaults.try_proxy) {
opts.proxy = defaults.try_proxy;
logger.debug("Setting proxy to " + opts.proxy);
}
send(1, method, path, data, opts, cb);
};

exports.get = function(path, opts, cb) {
send(1, 'GET', path, null, opts, cb);
}
set_proxy_and_send('GET', path, null, opts, cb);
};

exports.post = function(path, data, opts, cb) {
send(1, 'POST', path, data, opts, cb);
}
set_proxy_and_send('POST', path, data, opts, cb);
};

exports.delete = function(path, opts, cb) {
send(1, 'DELETE', path, null, opts, cb);
}
set_proxy_and_send('DELETE', path, null, opts, cb);
};

exports.use = function(obj) {
for (var key in obj) {
Expand All @@ -116,4 +143,4 @@ exports.use = function(obj) {
}
}
return defaults;
}
};
84 changes: 6 additions & 78 deletions lib/agent/plugins/control-panel/api/test/request_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,85 +8,13 @@ describe('API Request Wrapper', function() {
describe('.use', function() {

it('overrides defaults', function() {
var defaults = api_req.use({ host: 'http://foobar.com' });
var defaults = api_req.use({
host: 'http://foobar.com',
retry_timeout: 100
});
defaults.host.should.equal('http://foobar.com');
})
});

})

describe('get', function() {

var stub;

describe('on a 200 response', function() {

before(function() {
stub = sinon.stub(needle, 'request', function(method, url, data, opts, cb) {
cb(null, { statusCode: 200 });
})
})

after(function() {
stub.restore();
})

it('does not retry the request', function(done) {

api_req.get('/devices/something', {}, function(err, resp, body) {
stub.callCount.should.equal(1);
done();
})

})

})

describe('on a 503 response', function() {

before(function() {
stub = sinon.stub(needle, 'request', function(method, url, data, opts, cb) {
cb(new Error('socket hang up'));
})
})

after(function() {
stub.restore();
})

it('retries the request', function(done) {

api_req.get('/devices/something', {}, function(err, resp, body) {
stub.callCount.should.equal(3);
done();
})

})

})

describe('on connection error', function() {

before(function() {
stub = sinon.stub(needle, 'request', function(method, url, data, opts, cb) {
cb(new Error('socket hang up'));
})
})

after(function() {
stub.restore();
})

it('retries the request', function(done) {

api_req.get('/devices/something', {}, function(err, resp, body) {
stub.callCount.should.equal(3);
done();
})

})

})

})
});

});
Loading

0 comments on commit 3da96ce

Please sign in to comment.