Don't attempt to use workers if they fail to load
This commit is contained in:
parent
ecc8ae2a09
commit
34e6eacb2f
|
@ -119,7 +119,7 @@ Here are some examples of how to use the v2.x+ API. For more elaborate examples
|
|||
```js
|
||||
var openpgp = require('openpgp'); // use as CommonJS, AMD, ES6 module or via window.openpgp
|
||||
|
||||
openpgp.initWorker({ path:'openpgp.worker.js' }) // set the relative web worker path
|
||||
await openpgp.initWorker({ path:'openpgp.worker.js' }) // set the relative web worker path
|
||||
```
|
||||
|
||||
#### Encrypt and decrypt *Uint8Array* data with a password
|
||||
|
@ -159,7 +159,7 @@ Encryption will use the algorithm preferred by the public key (defaults to aes25
|
|||
```js
|
||||
const openpgp = require('openpgp') // use as CommonJS, AMD, ES6 module or via window.openpgp
|
||||
|
||||
openpgp.initWorker({ path:'openpgp.worker.js' }) // set the relative web worker path
|
||||
await openpgp.initWorker({ path:'openpgp.worker.js' }) // set the relative web worker path
|
||||
|
||||
// put keys in backtick (``) to avoid errors caused by spaces or tabs
|
||||
const pubkey = `-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
|
|
@ -63,12 +63,19 @@ let asyncProxy; // instance of the asyncproxy
|
|||
* @param {String} path relative path to the worker scripts, default: 'openpgp.worker.js'
|
||||
* @param {Number} n number of workers to initialize
|
||||
* @param {Array<Object>} workers alternative to path parameter: web workers initialized with 'openpgp.worker.js'
|
||||
* @returns {Promise<Boolean>} returns a promise that resolves to true if all workers have succesfully finished loading
|
||||
* @async
|
||||
*/
|
||||
export function initWorker({ path='openpgp.worker.js', n = 1, workers = [] } = {}) {
|
||||
export async function initWorker({ path='openpgp.worker.js', n = 1, workers = [] } = {}) {
|
||||
if (workers.length || (typeof window !== 'undefined' && window.Worker && window.MessageChannel)) {
|
||||
asyncProxy = new AsyncProxy({ path, n, workers, config });
|
||||
return true;
|
||||
const proxy = new AsyncProxy({ path, n, workers, config });
|
||||
const loaded = await proxy.loaded();
|
||||
if (loaded) {
|
||||
asyncProxy = proxy;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -49,6 +49,9 @@ function AsyncProxy({ path='openpgp.worker.js', n = 1, workers = [], config } =
|
|||
const handleMessage = workerId => event => {
|
||||
const msg = event.data;
|
||||
switch (msg.event) {
|
||||
case 'loaded':
|
||||
this.workers[workerId].loadedResolve(true);
|
||||
break;
|
||||
case 'method-return':
|
||||
if (msg.err) {
|
||||
// fail
|
||||
|
@ -83,10 +86,15 @@ function AsyncProxy({ path='openpgp.worker.js', n = 1, workers = [], config } =
|
|||
|
||||
let workerId = 0;
|
||||
this.workers.forEach(worker => {
|
||||
worker.loadedPromise = new Promise(resolve => {
|
||||
worker.loadedResolve = resolve;
|
||||
});
|
||||
worker.requests = 0;
|
||||
worker.onmessage = handleMessage(workerId++);
|
||||
worker.onerror = e => {
|
||||
throw new Error('Unhandled error in openpgp worker: ' + e.message + ' (' + e.filename + ':' + e.lineno + ')');
|
||||
worker.loadedResolve(false);
|
||||
console.error('Unhandled error in openpgp worker: ' + e.message + ' (' + e.filename + ':' + e.lineno + ')');
|
||||
return false;
|
||||
};
|
||||
|
||||
if (config) {
|
||||
|
@ -99,6 +107,15 @@ function AsyncProxy({ path='openpgp.worker.js', n = 1, workers = [], config } =
|
|||
this.currentID = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a promise that resolves when all workers have finished loading
|
||||
* @returns {Promise<Boolean>} Resolves to true if all workers have loaded succesfully; false otherwise
|
||||
*/
|
||||
AsyncProxy.prototype.loaded = async function() {
|
||||
const loaded = await Promise.all(this.workers.map(worker => worker.loadedPromise));
|
||||
return loaded.every(Boolean);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get new request ID
|
||||
* @returns {integer} New unique request ID
|
||||
|
|
|
@ -135,3 +135,8 @@ function delegate(id, method, options) {
|
|||
function response(event) {
|
||||
self.postMessage(event, openpgp.util.getTransferables(event.data, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Let the main window know the worker has loaded.
|
||||
*/
|
||||
postMessage({ event: 'loaded' });
|
||||
|
|
|
@ -273,8 +273,8 @@ describe('Brainpool Cryptography', function () {
|
|||
|
||||
tryTests('Brainpool Worker Tests', omnibus, {
|
||||
if: typeof window !== 'undefined' && window.Worker,
|
||||
before: function() {
|
||||
openpgp.initWorker({ path:'../dist/openpgp.worker.js' });
|
||||
before: async function() {
|
||||
await openpgp.initWorker({ path:'../dist/openpgp.worker.js' });
|
||||
},
|
||||
beforeEach: function() {
|
||||
openpgp.config.use_native = true;
|
||||
|
|
|
@ -297,8 +297,8 @@ describe('Elliptic Curve Cryptography', function () {
|
|||
|
||||
tryTests('ECC Worker Tests', omnibus, {
|
||||
if: typeof window !== 'undefined' && window.Worker,
|
||||
before: function() {
|
||||
openpgp.initWorker({ path:'../dist/openpgp.worker.js' });
|
||||
before: async function() {
|
||||
await openpgp.initWorker({ path:'../dist/openpgp.worker.js' });
|
||||
},
|
||||
beforeEach: function() {
|
||||
openpgp.config.use_native = true;
|
||||
|
|
|
@ -444,13 +444,16 @@ describe('[Sauce Labs Group 2] OpenPGP.js public api tests', function() {
|
|||
openpgp.destroyWorker(); // cleanup worker in case of failure
|
||||
});
|
||||
|
||||
it('should work', function() {
|
||||
it('should work', async function() {
|
||||
const workerStub = {
|
||||
postMessage: function() {}
|
||||
};
|
||||
openpgp.initWorker({
|
||||
workers: [workerStub]
|
||||
});
|
||||
await Promise.all([
|
||||
openpgp.initWorker({
|
||||
workers: [workerStub]
|
||||
}),
|
||||
workerStub.onmessage({ data: { event: 'loaded' } })
|
||||
]);
|
||||
expect(openpgp.getWorker()).to.exist;
|
||||
openpgp.destroyWorker();
|
||||
expect(openpgp.getWorker()).to.not.exist;
|
||||
|
@ -595,13 +598,16 @@ describe('[Sauce Labs Group 2] OpenPGP.js public api tests', function() {
|
|||
});
|
||||
});
|
||||
|
||||
it('should delegate to async proxy', function() {
|
||||
it('should delegate to async proxy', async function() {
|
||||
const workerStub = {
|
||||
postMessage: function() {}
|
||||
};
|
||||
openpgp.initWorker({
|
||||
workers: [workerStub]
|
||||
});
|
||||
await Promise.all([
|
||||
openpgp.initWorker({
|
||||
workers: [workerStub]
|
||||
}),
|
||||
workerStub.onmessage({ data: { event: 'loaded' } })
|
||||
]);
|
||||
const proxyGenStub = stub(openpgp.getWorker(), 'delegate');
|
||||
getWebCryptoAllStub.returns();
|
||||
|
||||
|
@ -643,9 +649,9 @@ describe('[Sauce Labs Group 2] OpenPGP.js public api tests', function() {
|
|||
});
|
||||
});
|
||||
|
||||
it('should work in JS (with worker)', function() {
|
||||
it('should work in JS (with worker)', async function() {
|
||||
openpgp.config.use_native = false;
|
||||
openpgp.initWorker({ path:'../dist/openpgp.worker.js' });
|
||||
await openpgp.initWorker({ path:'../dist/openpgp.worker.js' });
|
||||
const opt = {
|
||||
userIds: [{ name: 'Test User', email: 'text@example.com' }],
|
||||
numBits: 512
|
||||
|
@ -727,11 +733,11 @@ describe('[Sauce Labs Group 2] OpenPGP.js public api tests', function() {
|
|||
openpgp.config.aead_chunk_size_byte = aead_chunk_size_byteVal;
|
||||
});
|
||||
|
||||
it('Configuration', function() {
|
||||
it('Configuration', async function() {
|
||||
openpgp.config.show_version = false;
|
||||
openpgp.config.commentstring = 'different';
|
||||
if (openpgp.getWorker()) { // init again to trigger config event
|
||||
openpgp.initWorker({ path:'../dist/openpgp.worker.js' });
|
||||
await openpgp.initWorker({ path:'../dist/openpgp.worker.js' });
|
||||
}
|
||||
return openpgp.encrypt({ publicKeys:publicKey.keys, message:openpgp.message.fromText(plaintext) }).then(function(encrypted) {
|
||||
expect(encrypted.data).to.exist;
|
||||
|
@ -749,7 +755,7 @@ describe('[Sauce Labs Group 2] OpenPGP.js public api tests', function() {
|
|||
const { workers } = openpgp.getWorker();
|
||||
try {
|
||||
await privateKey.keys[0].decrypt(passphrase)
|
||||
openpgp.initWorker({path: '../dist/openpgp.worker.js', workers, n: 2});
|
||||
await openpgp.initWorker({path: '../dist/openpgp.worker.js', workers, n: 2});
|
||||
|
||||
const workerTest = (_, index) => {
|
||||
const plaintext = input.createSomeMessage() + index;
|
||||
|
@ -770,7 +776,7 @@ describe('[Sauce Labs Group 2] OpenPGP.js public api tests', function() {
|
|||
};
|
||||
await Promise.all(Array(10).fill(null).map(workerTest));
|
||||
} finally {
|
||||
openpgp.initWorker({path: '../dist/openpgp.worker.js', workers, n: 1 });
|
||||
await openpgp.initWorker({path: '../dist/openpgp.worker.js', workers, n: 1 });
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -828,8 +834,8 @@ describe('[Sauce Labs Group 2] OpenPGP.js public api tests', function() {
|
|||
|
||||
tryTests('CFB mode (asm.js, worker)', tests, {
|
||||
if: typeof window !== 'undefined' && window.Worker,
|
||||
before: function() {
|
||||
openpgp.initWorker({ path:'../dist/openpgp.worker.js' });
|
||||
before: async function() {
|
||||
await openpgp.initWorker({ path:'../dist/openpgp.worker.js' });
|
||||
},
|
||||
beforeEach: function() {
|
||||
openpgp.config.aead_protect = false;
|
||||
|
|
|
@ -319,8 +319,8 @@ describe('X25519 Cryptography', function () {
|
|||
|
||||
tryTests('X25519 Worker Tests', omnibus, {
|
||||
if: typeof window !== 'undefined' && window.Worker,
|
||||
before: function() {
|
||||
openpgp.initWorker({ path:'../dist/openpgp.worker.js' });
|
||||
before: async function() {
|
||||
await openpgp.initWorker({ path:'../dist/openpgp.worker.js' });
|
||||
},
|
||||
beforeEach: function() {
|
||||
openpgp.config.use_native = true;
|
||||
|
|
|
@ -37,7 +37,7 @@ let pubKey;
|
|||
tryTests('Async Proxy', tests, {
|
||||
if: typeof window !== 'undefined' && window.Worker && window.MessageChannel,
|
||||
before: async function() {
|
||||
openpgp.initWorker({ path:'../dist/openpgp.worker.js' });
|
||||
await openpgp.initWorker({ path:'../dist/openpgp.worker.js' });
|
||||
pubKey = (await openpgp.key.readArmored(pub_key)).keys[0];
|
||||
},
|
||||
after: function() {
|
||||
|
@ -48,11 +48,13 @@ tryTests('Async Proxy', tests, {
|
|||
function tests() {
|
||||
|
||||
describe('Random number pipeline', function() {
|
||||
it('Random number buffer automatically reseeded', function() {
|
||||
it('Random number buffer automatically reseeded', async function() {
|
||||
const worker = new Worker('../dist/openpgp.worker.js');
|
||||
const wProxy = new openpgp.AsyncProxy({ path:'../dist/openpgp.worker.js', workers: [worker] });
|
||||
|
||||
return wProxy.delegate('encrypt', { publicKeys:[pubKey], message:openpgp.message.fromText(plaintext) });
|
||||
const loaded = await wProxy.loaded();
|
||||
if (loaded) {
|
||||
return wProxy.delegate('encrypt', { publicKeys:[pubKey], message:openpgp.message.fromText(plaintext) });
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user