extracted blobSlicer, fixed download cancel tests
This commit is contained in:
parent
5483dc2506
commit
5e9e63944b
27
app/blobSlicer.js
Normal file
27
app/blobSlicer.js
Normal file
@ -0,0 +1,27 @@
|
||||
export default class BlobSlicer {
|
||||
constructor(blob, size) {
|
||||
this.blob = blob;
|
||||
this.index = 0;
|
||||
this.chunkSize = size;
|
||||
}
|
||||
|
||||
pull(controller) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const bytesLeft = this.blob.size - this.index;
|
||||
if (bytesLeft <= 0) {
|
||||
controller.close();
|
||||
return resolve();
|
||||
}
|
||||
const size = Math.min(this.chunkSize, bytesLeft);
|
||||
const blob = this.blob.slice(this.index, this.index + size);
|
||||
const reader = new FileReader();
|
||||
reader.onload = () => {
|
||||
controller.enqueue(new Uint8Array(reader.result));
|
||||
resolve();
|
||||
};
|
||||
reader.onerror = reject;
|
||||
reader.readAsArrayBuffer(blob);
|
||||
this.index += size;
|
||||
});
|
||||
}
|
||||
}
|
37
app/ece.js
37
app/ece.js
@ -1,4 +1,5 @@
|
||||
import 'buffer';
|
||||
import BlobSlicer from './blobSlicer';
|
||||
import { transformStream } from './streams';
|
||||
|
||||
const NONCE_LENGTH = 12;
|
||||
@ -225,40 +226,6 @@ class ECETransformer {
|
||||
}
|
||||
}
|
||||
|
||||
export class BlobSlicer {
|
||||
constructor(blob, rs, mode) {
|
||||
this.blob = blob;
|
||||
this.index = 0;
|
||||
this.mode = mode;
|
||||
this.chunkSize = mode === MODE_ENCRYPT ? rs - 17 : rs;
|
||||
}
|
||||
|
||||
pull(controller) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const bytesLeft = this.blob.size - this.index;
|
||||
if (bytesLeft <= 0) {
|
||||
controller.close();
|
||||
return resolve();
|
||||
}
|
||||
let size = 1;
|
||||
if (this.mode === MODE_DECRYPT && this.index === 0) {
|
||||
size = Math.min(21, bytesLeft);
|
||||
} else {
|
||||
size = Math.min(this.chunkSize, bytesLeft);
|
||||
}
|
||||
const blob = this.blob.slice(this.index, this.index + size);
|
||||
const reader = new FileReader();
|
||||
reader.onload = () => {
|
||||
controller.enqueue(new Uint8Array(reader.result));
|
||||
resolve();
|
||||
};
|
||||
reader.onerror = reject;
|
||||
reader.readAsArrayBuffer(blob);
|
||||
this.index += size;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class StreamSlicer {
|
||||
constructor(rs, mode) {
|
||||
this.mode = mode;
|
||||
@ -350,7 +317,7 @@ export default class ECE {
|
||||
|
||||
if (this.input instanceof Blob) {
|
||||
inputStream = new ReadableStream(
|
||||
new BlobSlicer(this.input, this.rs, this.mode)
|
||||
new BlobSlicer(this.input, this.rs - 17)
|
||||
);
|
||||
} else {
|
||||
inputStream = transformStream(
|
||||
|
@ -148,7 +148,7 @@ export default class FileReceiver extends Nanobus {
|
||||
this.state = 'complete';
|
||||
} catch (e) {
|
||||
this.downloadRequest = null;
|
||||
if (e === 'cancelled') {
|
||||
if (e === 'cancelled' || e.message === '400') {
|
||||
throw new Error(0);
|
||||
}
|
||||
throw e;
|
||||
|
@ -15,8 +15,11 @@ self.addEventListener('activate', event => {
|
||||
});
|
||||
|
||||
async function decryptStream(id) {
|
||||
try {
|
||||
const file = map.get(id);
|
||||
if (!file) {
|
||||
return new Response(null, { status: 400 });
|
||||
}
|
||||
try {
|
||||
const keychain = new Keychain(file.key, file.nonce);
|
||||
if (file.requiresPassword) {
|
||||
keychain.setPassword(file.password, file.url);
|
||||
|
@ -3,6 +3,7 @@ require('buffer');
|
||||
|
||||
import assert from 'assert';
|
||||
import { b64ToArray } from '../../../app/utils';
|
||||
import BlobSlicer from '../../../app/blobSlicer';
|
||||
import ECE from '../../../app/ece.js';
|
||||
|
||||
const rs = 36;
|
||||
@ -47,8 +48,10 @@ describe('Streaming', function() {
|
||||
});
|
||||
|
||||
it('can decrypt', async function() {
|
||||
const encBlob = new Blob([encrypted]);
|
||||
const ece = new ECE(encBlob, key, 'decrypt', rs);
|
||||
const blobStream = new ReadableStream(
|
||||
new BlobSlicer(new Blob([encrypted]), rs)
|
||||
);
|
||||
const ece = new ECE(blobStream, key, 'decrypt', rs);
|
||||
const decStream = await ece.transform();
|
||||
|
||||
const reader = decStream.getReader();
|
||||
|
@ -153,26 +153,26 @@ describe('Upload / Download flow', function() {
|
||||
assert.equal(file.dtotal, 1);
|
||||
});
|
||||
|
||||
// it('does not increase download count when download cancelled', async function() {
|
||||
// const fs = new FileSender(blob);
|
||||
// const file = await fs.upload();
|
||||
// const fr = new FileReceiver({
|
||||
// secretKey: file.toJSON().secretKey,
|
||||
// id: file.id,
|
||||
// nonce: file.keychain.nonce,
|
||||
// requiresPassword: false
|
||||
// });
|
||||
// await fr.getMetadata();
|
||||
// fr.once('progress', () => fr.cancel());
|
||||
it('does not increase download count when download cancelled', async function() {
|
||||
const fs = new FileSender(blob);
|
||||
const file = await fs.upload();
|
||||
const fr = new FileReceiver({
|
||||
secretKey: file.toJSON().secretKey,
|
||||
id: file.id,
|
||||
nonce: file.keychain.nonce,
|
||||
requiresPassword: false
|
||||
});
|
||||
await fr.getMetadata();
|
||||
fr.once('progress', () => fr.cancel());
|
||||
|
||||
// try {
|
||||
// await fr.download(noSave);
|
||||
// assert.fail('not cancelled');
|
||||
// } catch (e) {
|
||||
// await file.updateDownloadCount();
|
||||
// assert.equal(file.dtotal, 0);
|
||||
// }
|
||||
// });
|
||||
try {
|
||||
await fr.download(noSave);
|
||||
assert.fail('not cancelled');
|
||||
} catch (e) {
|
||||
await file.updateDownloadCount();
|
||||
assert.equal(file.dtotal, 0);
|
||||
}
|
||||
});
|
||||
|
||||
it('can allow multiple downloads', async function() {
|
||||
const fs = new FileSender(blob);
|
||||
|
Loading…
Reference in New Issue
Block a user