addressing race condition mentioned in issue #72
This commit is contained in:
parent
da2cc50061
commit
3a1324f464
44
lib/core.js
44
lib/core.js
|
@ -14,6 +14,7 @@ module.exports.create = function (le) {
|
||||||
var utils = require('./utils');
|
var utils = require('./utils');
|
||||||
var RSA = PromiseA.promisifyAll(require('rsa-compat').RSA);
|
var RSA = PromiseA.promisifyAll(require('rsa-compat').RSA);
|
||||||
var log = le.log || _log; // allow custom log
|
var log = le.log || _log; // allow custom log
|
||||||
|
var pendingRegistrations = {};
|
||||||
|
|
||||||
var core = {
|
var core = {
|
||||||
//
|
//
|
||||||
|
@ -183,13 +184,45 @@ module.exports.create = function (le) {
|
||||||
return PromiseA.reject(err);
|
return PromiseA.reject(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If a previous request to (re)register a certificate is already underway we need
|
||||||
|
// to return the same promise created before rather than registering things twice.
|
||||||
|
// I'm not 100% sure how to properly handle the case where someone registers domain
|
||||||
|
// lists with some but not all elements common, nor am I sure that's even a case that
|
||||||
|
// is allowed to happen anyway. But for now we act like the list is completely the
|
||||||
|
// same if any elements are the same.
|
||||||
|
var promise;
|
||||||
|
args.domains.some(function (name) {
|
||||||
|
if (pendingRegistrations.hasOwnProperty(name)) {
|
||||||
|
promise = pendingRegistrations[name];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (promise) {
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
promise = core.certificates._runRegistration(args);
|
||||||
|
|
||||||
|
// Now that the registration is actually underway we need to make sure any subsequent
|
||||||
|
// registration attempts return the same promise until it is completed (but not after
|
||||||
|
// it is completed).
|
||||||
|
args.domains.forEach(function (name) {
|
||||||
|
pendingRegistrations[name] = promise;
|
||||||
|
});
|
||||||
|
function clearPending() {
|
||||||
|
args.domains.forEach(function (name) {
|
||||||
|
delete pendingRegistrations[name];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
promise.then(clearPending, clearPending);
|
||||||
|
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
, _runRegistration: function (args) {
|
||||||
// TODO renewal cb
|
// TODO renewal cb
|
||||||
// accountId and or email
|
// accountId and or email
|
||||||
return core.accounts.getAsync(copy).then(function (account) {
|
return core.accounts.getAsync(args).then(function (account) {
|
||||||
copy.account = account;
|
args.account = account;
|
||||||
|
|
||||||
//var account = args.account;
|
|
||||||
var keypairOpts = { public: true, pem: true };
|
|
||||||
|
|
||||||
var promise = le.store.certificates.checkKeypairAsync(args).then(function (keypair) {
|
var promise = le.store.certificates.checkKeypairAsync(args).then(function (keypair) {
|
||||||
if (keypair) {
|
if (keypair) {
|
||||||
|
@ -200,6 +233,7 @@ module.exports.create = function (le) {
|
||||||
return le.store.certificates.setKeypairAsync(args, RSA.import(args.domainKeypair));
|
return le.store.certificates.setKeypairAsync(args, RSA.import(args.domainKeypair));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var keypairOpts = { public: true, pem: true };
|
||||||
return RSA.generateKeypairAsync(args.rsaKeySize, 65537, keypairOpts).then(function (keypair) {
|
return RSA.generateKeypairAsync(args.rsaKeySize, 65537, keypairOpts).then(function (keypair) {
|
||||||
keypair.privateKeyPem = RSA.exportPrivatePem(keypair);
|
keypair.privateKeyPem = RSA.exportPrivatePem(keypair);
|
||||||
keypair.publicKeyPem = RSA.exportPublicPem(keypair);
|
keypair.publicKeyPem = RSA.exportPublicPem(keypair);
|
||||||
|
|
Loading…
Reference in New Issue