add streaming

This commit is contained in:
Emily Hou 2018-06-21 13:57:53 -07:00
parent 1bd7e4d486
commit e4a0028f5d
4 changed files with 50 additions and 41 deletions

View File

@ -107,7 +107,8 @@ async function upload(
metadata, metadata,
verifierB64, verifierB64,
keychain, keychain,
onprogress onprogress,
canceller
) { ) {
const metadataHeader = arrayToB64(new Uint8Array(metadata)); const metadataHeader = arrayToB64(new Uint8Array(metadata));
const fileMeta = { const fileMeta = {
@ -115,23 +116,25 @@ async function upload(
authorization: `send-v1 ${verifierB64}` authorization: `send-v1 ${verifierB64}`
}; };
//send file header function listenForResponse() {
ws.send(JSON.stringify(fileMeta));
function listenForRes() {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
ws.addEventListener('message', function(msg) { ws.addEventListener('message', function(msg) {
const response = JSON.parse(msg.data); const response = JSON.parse(msg.data);
resolve({ if (response.error) {
url: response.url, reject(response.error);
id: response.id, } else {
ownerToken: response.owner resolve({
}); url: response.url,
id: response.id,
ownerToken: response.owner
});
}
}); });
}); });
} }
const resPromise = listenForRes(); const resPromise = listenForResponse();
ws.send(JSON.stringify(fileMeta));
const reader = stream.getReader(); const reader = stream.getReader();
let state = await reader.read(); let state = await reader.read();
@ -139,8 +142,9 @@ async function upload(
while (!state.done) { while (!state.done) {
const buf = state.value; const buf = state.value;
ws.send(buf); ws.send(buf);
if (ws.readyState !== 1) {
throw new Error(0); //should this be here if (canceller.cancelled) {
throw new Error(0);
} }
onprogress([Math.min(streamInfo.fileSize, size), streamInfo.fileSize]); onprogress([Math.min(streamInfo.fileSize, size), streamInfo.fileSize]);
@ -148,10 +152,10 @@ async function upload(
state = await reader.read(); state = await reader.read();
} }
const res = await resPromise; const response = await resPromise;
ws.close(); ws.close();
return res; return response;
} }
export async function uploadWs( export async function uploadWs(
@ -166,12 +170,12 @@ export async function uploadWs(
const port = window.location.port; const port = window.location.port;
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'; const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
const ws = await asyncInitWebSocket(`${protocol}//${host}:${port}/api/ws`); const ws = await asyncInitWebSocket(`${protocol}//${host}:${port}/api/ws`);
const canceller = { cancelled: false };
//console.log(`made connection to websocket: ws://${host}:${port}/api/ws`)
return { return {
cancel: function() { cancel: function() {
ws.close(4000, 'upload cancelled'); ws.close(4000, 'upload cancelled');
canceller.cancelled = true;
}, },
result: upload( result: upload(
ws, ws,
@ -180,7 +184,8 @@ export async function uploadWs(
metadata, metadata,
verifierB64, verifierB64,
keychain, keychain,
onprogress onprogress,
canceller
) )
}; };
} }

View File

@ -6,7 +6,7 @@ const TAG_LENGTH = 16;
const KEY_LENGTH = 16; const KEY_LENGTH = 16;
const MODE_ENCRYPT = 'encrypt'; const MODE_ENCRYPT = 'encrypt';
const MODE_DECRYPT = 'decrypt'; const MODE_DECRYPT = 'decrypt';
const RS = 1024 * 1024; const RS = 1048576;
const encoder = new TextEncoder(); const encoder = new TextEncoder();
@ -16,7 +16,7 @@ function generateSalt(len) {
return randSalt.buffer; return randSalt.buffer;
} }
export class ECETransformer { class ECETransformer {
constructor(mode, ikm, rs, salt) { constructor(mode, ikm, rs, salt) {
this.mode = mode; this.mode = mode;
this.prevChunk; this.prevChunk;
@ -139,7 +139,6 @@ export class ECETransformer {
return Buffer.concat([Buffer.from(this.salt), nums]); return Buffer.concat([Buffer.from(this.salt), nums]);
} }
//salt is arraybuffer, rs is int, length is int
readHeader(buffer) { readHeader(buffer) {
if (buffer.length < 21) { if (buffer.length < 21) {
throw new Error('chunk too small for reading header'); throw new Error('chunk too small for reading header');
@ -259,7 +258,7 @@ class BlobSlicer {
} }
} }
export class BlobSliceStream extends ReadableStream { class BlobSliceStream extends ReadableStream {
constructor(blob, size, mode) { constructor(blob, size, mode) {
super(new BlobSlicer(blob, size, mode)); super(new BlobSlicer(blob, size, mode));
} }
@ -272,7 +271,6 @@ mode: string, either 'encrypt' or 'decrypt'
rs: int containing record size, optional rs: int containing record size, optional
salt: ArrayBuffer containing salt of KEY_LENGTH length, optional salt: ArrayBuffer containing salt of KEY_LENGTH length, optional
*/ */
export default class ECE { export default class ECE {
constructor(input, key, mode, rs, salt) { constructor(input, key, mode, rs, salt) {
if (rs === undefined) { if (rs === undefined) {

View File

@ -12,7 +12,7 @@ if (config.sentry_dsn) {
const app = express(); const app = express();
expressWs(app, null, { perMessageDeflate: false }); expressWs(app, null, { perMessageDeflate: false });
app.ws('/api/ws', require('./routes/ws')); //want to move this into routes/index.js but it's not working... app.ws('/api/ws', require('./routes/ws'));
routes(app); routes(app);
app.use( app.use(

View File

@ -10,17 +10,17 @@ const log = mozlog('send.upload');
module.exports = async function(ws, req) { module.exports = async function(ws, req) {
let fileStream; let fileStream;
try { ws.on('close', e => {
ws.on('close', e => { if (e !== 1000) {
if (e !== 1000) { if (fileStream !== undefined) {
if (fileStream !== undefined) { fileStream.destroy();
fileStream.destroy();
}
} }
}); }
});
let first = true; let first = true;
ws.on('message', function(message) { ws.on('message', function(message) {
try {
if (first) { if (first) {
const newId = crypto.randomBytes(5).toString('hex'); const newId = crypto.randomBytes(5).toString('hex');
const owner = crypto.randomBytes(10).toString('hex'); const owner = crypto.randomBytes(10).toString('hex');
@ -29,11 +29,13 @@ module.exports = async function(ws, req) {
const metadata = fileInfo.fileMetadata; const metadata = fileInfo.fileMetadata;
const auth = fileInfo.authorization; const auth = fileInfo.authorization;
/*
if (!metadata || !auth) { if (!metadata || !auth) {
return res.sendStatus(400); ws.send(
JSON.stringify({
error: 400
})
);
} }
*/
const meta = { const meta = {
owner, owner,
@ -60,9 +62,13 @@ module.exports = async function(ws, req) {
first = false; first = false;
} }
}); } catch (e) {
} catch (e) { log.error('upload', e);
log.error('upload', e); ws.send(
//res.sendStatus(500); JSON.stringify({
} error: 500
})
);
}
});
}; };