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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user