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
|
```js
|
||||||
var openpgp = require('openpgp'); // use as CommonJS, AMD, ES6 module or via window.openpgp
|
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
|
#### 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
|
```js
|
||||||
const openpgp = require('openpgp') // use as CommonJS, AMD, ES6 module or via window.openpgp
|
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
|
// put keys in backtick (``) to avoid errors caused by spaces or tabs
|
||||||
const pubkey = `-----BEGIN PGP PUBLIC KEY BLOCK-----
|
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 {String} path relative path to the worker scripts, default: 'openpgp.worker.js'
|
||||||
* @param {Number} n number of workers to initialize
|
* @param {Number} n number of workers to initialize
|
||||||
* @param {Array<Object>} workers alternative to path parameter: web workers initialized with 'openpgp.worker.js'
|
* @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)) {
|
if (workers.length || (typeof window !== 'undefined' && window.Worker && window.MessageChannel)) {
|
||||||
asyncProxy = new AsyncProxy({ path, n, workers, config });
|
const proxy = new AsyncProxy({ path, n, workers, config });
|
||||||
return true;
|
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 handleMessage = workerId => event => {
|
||||||
const msg = event.data;
|
const msg = event.data;
|
||||||
switch (msg.event) {
|
switch (msg.event) {
|
||||||
|
case 'loaded':
|
||||||
|
this.workers[workerId].loadedResolve(true);
|
||||||
|
break;
|
||||||
case 'method-return':
|
case 'method-return':
|
||||||
if (msg.err) {
|
if (msg.err) {
|
||||||
// fail
|
// fail
|
||||||
|
@ -83,10 +86,15 @@ function AsyncProxy({ path='openpgp.worker.js', n = 1, workers = [], config } =
|
||||||
|
|
||||||
let workerId = 0;
|
let workerId = 0;
|
||||||
this.workers.forEach(worker => {
|
this.workers.forEach(worker => {
|
||||||
|
worker.loadedPromise = new Promise(resolve => {
|
||||||
|
worker.loadedResolve = resolve;
|
||||||
|
});
|
||||||
worker.requests = 0;
|
worker.requests = 0;
|
||||||
worker.onmessage = handleMessage(workerId++);
|
worker.onmessage = handleMessage(workerId++);
|
||||||
worker.onerror = e => {
|
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) {
|
if (config) {
|
||||||
|
@ -99,6 +107,15 @@ function AsyncProxy({ path='openpgp.worker.js', n = 1, workers = [], config } =
|
||||||
this.currentID = 0;
|
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
|
* Get new request ID
|
||||||
* @returns {integer} New unique request ID
|
* @returns {integer} New unique request ID
|
||||||
|
|
|
@ -135,3 +135,8 @@ function delegate(id, method, options) {
|
||||||
function response(event) {
|
function response(event) {
|
||||||
self.postMessage(event, openpgp.util.getTransferables(event.data, true));
|
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, {
|
tryTests('Brainpool Worker Tests', omnibus, {
|
||||||
if: typeof window !== 'undefined' && window.Worker,
|
if: typeof window !== 'undefined' && window.Worker,
|
||||||
before: function() {
|
before: async function() {
|
||||||
openpgp.initWorker({ path:'../dist/openpgp.worker.js' });
|
await openpgp.initWorker({ path:'../dist/openpgp.worker.js' });
|
||||||
},
|
},
|
||||||
beforeEach: function() {
|
beforeEach: function() {
|
||||||
openpgp.config.use_native = true;
|
openpgp.config.use_native = true;
|
||||||
|
|
|
@ -297,8 +297,8 @@ describe('Elliptic Curve Cryptography', function () {
|
||||||
|
|
||||||
tryTests('ECC Worker Tests', omnibus, {
|
tryTests('ECC Worker Tests', omnibus, {
|
||||||
if: typeof window !== 'undefined' && window.Worker,
|
if: typeof window !== 'undefined' && window.Worker,
|
||||||
before: function() {
|
before: async function() {
|
||||||
openpgp.initWorker({ path:'../dist/openpgp.worker.js' });
|
await openpgp.initWorker({ path:'../dist/openpgp.worker.js' });
|
||||||
},
|
},
|
||||||
beforeEach: function() {
|
beforeEach: function() {
|
||||||
openpgp.config.use_native = true;
|
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
|
openpgp.destroyWorker(); // cleanup worker in case of failure
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work', function() {
|
it('should work', async function() {
|
||||||
const workerStub = {
|
const workerStub = {
|
||||||
postMessage: function() {}
|
postMessage: function() {}
|
||||||
};
|
};
|
||||||
openpgp.initWorker({
|
await Promise.all([
|
||||||
workers: [workerStub]
|
openpgp.initWorker({
|
||||||
});
|
workers: [workerStub]
|
||||||
|
}),
|
||||||
|
workerStub.onmessage({ data: { event: 'loaded' } })
|
||||||
|
]);
|
||||||
expect(openpgp.getWorker()).to.exist;
|
expect(openpgp.getWorker()).to.exist;
|
||||||
openpgp.destroyWorker();
|
openpgp.destroyWorker();
|
||||||
expect(openpgp.getWorker()).to.not.exist;
|
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 = {
|
const workerStub = {
|
||||||
postMessage: function() {}
|
postMessage: function() {}
|
||||||
};
|
};
|
||||||
openpgp.initWorker({
|
await Promise.all([
|
||||||
workers: [workerStub]
|
openpgp.initWorker({
|
||||||
});
|
workers: [workerStub]
|
||||||
|
}),
|
||||||
|
workerStub.onmessage({ data: { event: 'loaded' } })
|
||||||
|
]);
|
||||||
const proxyGenStub = stub(openpgp.getWorker(), 'delegate');
|
const proxyGenStub = stub(openpgp.getWorker(), 'delegate');
|
||||||
getWebCryptoAllStub.returns();
|
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.config.use_native = false;
|
||||||
openpgp.initWorker({ path:'../dist/openpgp.worker.js' });
|
await openpgp.initWorker({ path:'../dist/openpgp.worker.js' });
|
||||||
const opt = {
|
const opt = {
|
||||||
userIds: [{ name: 'Test User', email: 'text@example.com' }],
|
userIds: [{ name: 'Test User', email: 'text@example.com' }],
|
||||||
numBits: 512
|
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;
|
openpgp.config.aead_chunk_size_byte = aead_chunk_size_byteVal;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Configuration', function() {
|
it('Configuration', async function() {
|
||||||
openpgp.config.show_version = false;
|
openpgp.config.show_version = false;
|
||||||
openpgp.config.commentstring = 'different';
|
openpgp.config.commentstring = 'different';
|
||||||
if (openpgp.getWorker()) { // init again to trigger config event
|
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) {
|
return openpgp.encrypt({ publicKeys:publicKey.keys, message:openpgp.message.fromText(plaintext) }).then(function(encrypted) {
|
||||||
expect(encrypted.data).to.exist;
|
expect(encrypted.data).to.exist;
|
||||||
|
@ -749,7 +755,7 @@ describe('[Sauce Labs Group 2] OpenPGP.js public api tests', function() {
|
||||||
const { workers } = openpgp.getWorker();
|
const { workers } = openpgp.getWorker();
|
||||||
try {
|
try {
|
||||||
await privateKey.keys[0].decrypt(passphrase)
|
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 workerTest = (_, index) => {
|
||||||
const plaintext = input.createSomeMessage() + 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));
|
await Promise.all(Array(10).fill(null).map(workerTest));
|
||||||
} finally {
|
} 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, {
|
tryTests('CFB mode (asm.js, worker)', tests, {
|
||||||
if: typeof window !== 'undefined' && window.Worker,
|
if: typeof window !== 'undefined' && window.Worker,
|
||||||
before: function() {
|
before: async function() {
|
||||||
openpgp.initWorker({ path:'../dist/openpgp.worker.js' });
|
await openpgp.initWorker({ path:'../dist/openpgp.worker.js' });
|
||||||
},
|
},
|
||||||
beforeEach: function() {
|
beforeEach: function() {
|
||||||
openpgp.config.aead_protect = false;
|
openpgp.config.aead_protect = false;
|
||||||
|
|
|
@ -319,8 +319,8 @@ describe('X25519 Cryptography', function () {
|
||||||
|
|
||||||
tryTests('X25519 Worker Tests', omnibus, {
|
tryTests('X25519 Worker Tests', omnibus, {
|
||||||
if: typeof window !== 'undefined' && window.Worker,
|
if: typeof window !== 'undefined' && window.Worker,
|
||||||
before: function() {
|
before: async function() {
|
||||||
openpgp.initWorker({ path:'../dist/openpgp.worker.js' });
|
await openpgp.initWorker({ path:'../dist/openpgp.worker.js' });
|
||||||
},
|
},
|
||||||
beforeEach: function() {
|
beforeEach: function() {
|
||||||
openpgp.config.use_native = true;
|
openpgp.config.use_native = true;
|
||||||
|
|
|
@ -37,7 +37,7 @@ let pubKey;
|
||||||
tryTests('Async Proxy', tests, {
|
tryTests('Async Proxy', tests, {
|
||||||
if: typeof window !== 'undefined' && window.Worker && window.MessageChannel,
|
if: typeof window !== 'undefined' && window.Worker && window.MessageChannel,
|
||||||
before: async function() {
|
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];
|
pubKey = (await openpgp.key.readArmored(pub_key)).keys[0];
|
||||||
},
|
},
|
||||||
after: function() {
|
after: function() {
|
||||||
|
@ -48,11 +48,13 @@ tryTests('Async Proxy', tests, {
|
||||||
function tests() {
|
function tests() {
|
||||||
|
|
||||||
describe('Random number pipeline', function() {
|
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 worker = new Worker('../dist/openpgp.worker.js');
|
||||||
const wProxy = new openpgp.AsyncProxy({ path:'../dist/openpgp.worker.js', workers: [worker] });
|
const wProxy = new openpgp.AsyncProxy({ path:'../dist/openpgp.worker.js', workers: [worker] });
|
||||||
|
const loaded = await wProxy.loaded();
|
||||||
return wProxy.delegate('encrypt', { publicKeys:[pubKey], message:openpgp.message.fromText(plaintext) });
|
if (loaded) {
|
||||||
|
return wProxy.delegate('encrypt', { publicKeys:[pubKey], message:openpgp.message.fromText(plaintext) });
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user