mirror of
https://github.com/jech/galene.git
synced 2024-11-26 02:25:58 +01:00
Fix file transfer for Firefox.
Firefox implements the spec correctly by encapsulatings received data in a blob by default. Handle both blobs and ArrayBuffers. Also improve error handling.
This commit is contained in:
parent
6d250bfa98
commit
60ba4aa727
1 changed files with 61 additions and 14 deletions
|
@ -2163,7 +2163,7 @@ async function gotJoined(kind, group, perms, status, data, message) {
|
||||||
* @property {number} size
|
* @property {number} size
|
||||||
* @property {string} type
|
* @property {string} type
|
||||||
* @property {Array<RTCIceCandidateInit>} [candidates]
|
* @property {Array<RTCIceCandidateInit>} [candidates]
|
||||||
* @property {Array<Uint8Array>} [data]
|
* @property {Array<Blob|ArrayBuffer>} [data]
|
||||||
* @property {number} [datalen]
|
* @property {number} [datalen]
|
||||||
* @property {boolean} [done]
|
* @property {boolean} [done]
|
||||||
*/
|
*/
|
||||||
|
@ -2302,6 +2302,18 @@ function setFileStatus(up, id, fileid, status, delyes, delno) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {boolean} up
|
||||||
|
* @param {string} id
|
||||||
|
* @param {string} fileid
|
||||||
|
* @param {any} message
|
||||||
|
*/
|
||||||
|
function failFile(up, id, fileid, message) {
|
||||||
|
console.error('File transfer failed:', message);
|
||||||
|
setFileStatus(up, id, fileid, message ? `Failed: ${message}` : 'Failed.');
|
||||||
|
deleteTransferredFile(true, id, fileid);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} username
|
* @param {string} username
|
||||||
* @param {string} id
|
* @param {string} id
|
||||||
|
@ -2374,11 +2386,24 @@ async function getFile(id, fileid) {
|
||||||
f.data = [];
|
f.data = [];
|
||||||
f.datalen = 0;
|
f.datalen = 0;
|
||||||
dc.onclose = function(e) {
|
dc.onclose = function(e) {
|
||||||
closeReceiveFileData(id, fileid, f);
|
try {
|
||||||
}
|
closeReceiveFileData(id, fileid, f);
|
||||||
|
} catch(e) {
|
||||||
|
failFile(false, id, fileid, e);
|
||||||
|
}
|
||||||
|
};
|
||||||
dc.onmessage = function(e) {
|
dc.onmessage = function(e) {
|
||||||
receiveFileData(id, fileid, f, dc, e.data);
|
try {
|
||||||
}
|
receiveFileData(id, fileid, f, dc, e.data);
|
||||||
|
} catch(e) {
|
||||||
|
failFile(false, id, fileid, e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
dc.onerror = function(e) {
|
||||||
|
/** @ts-ignore */
|
||||||
|
let err = e.error;
|
||||||
|
failFile(false, id, fileid, err);
|
||||||
|
};
|
||||||
let offer = await pc.createOffer();
|
let offer = await pc.createOffer();
|
||||||
if(!offer)
|
if(!offer)
|
||||||
throw new Error("Couldn't create offer");
|
throw new Error("Couldn't create offer");
|
||||||
|
@ -2433,16 +2458,27 @@ async function sendFile(id, fileid, sdp) {
|
||||||
};
|
};
|
||||||
let file = f.file;
|
let file = f.file;
|
||||||
pc.ondatachannel = function(e) {
|
pc.ondatachannel = function(e) {
|
||||||
e.channel.onopen = function(e) {
|
let dc = /** @type{RTCDataChannel} */(e.channel);
|
||||||
let dc = /** @type{RTCDataChannel} */(e.target);
|
dc.onclose = function(e) {
|
||||||
dc.onmessage = function(e) {
|
try {
|
||||||
ackSendFileData(id, fileid, f, e.data);
|
|
||||||
}
|
|
||||||
dc.onclose = function(e) {
|
|
||||||
closeSendFileData(id, fileid, f);
|
closeSendFileData(id, fileid, f);
|
||||||
|
} catch(e) {
|
||||||
|
failFile(true, id, fileid, e);
|
||||||
}
|
}
|
||||||
sendFileData(id, fileid, f, dc, file);
|
};
|
||||||
|
dc.onerror = function(e) {
|
||||||
|
/** @ts-ignore */
|
||||||
|
let err = e.error;
|
||||||
|
failFile(true, id, fileid, err);
|
||||||
}
|
}
|
||||||
|
dc.onmessage = function(e) {
|
||||||
|
try {
|
||||||
|
ackSendFileData(id, fileid, f, e.data);
|
||||||
|
} catch(e) {
|
||||||
|
failFile(true, id, fileid, e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
sendFileData(id, fileid, f, dc, file);
|
||||||
};
|
};
|
||||||
|
|
||||||
await pc.setRemoteDescription({
|
await pc.setRemoteDescription({
|
||||||
|
@ -2552,11 +2588,19 @@ function closeSendFileData(id, fileid, f) {
|
||||||
* @param {string} fileid
|
* @param {string} fileid
|
||||||
* @param {transferredFile} f
|
* @param {transferredFile} f
|
||||||
* @param {RTCDataChannel} dc
|
* @param {RTCDataChannel} dc
|
||||||
* @param {Uint8Array} data
|
* @param {Blob|ArrayBuffer} data
|
||||||
*/
|
*/
|
||||||
function receiveFileData(id, fileid, f, dc, data) {
|
function receiveFileData(id, fileid, f, dc, data) {
|
||||||
f.data.push(data);
|
f.data.push(data);
|
||||||
f.datalen += data.byteLength;
|
if(data instanceof Blob) {
|
||||||
|
f.datalen += data.size;
|
||||||
|
} else if(data instanceof ArrayBuffer) {
|
||||||
|
f.datalen += data.byteLength;
|
||||||
|
} else {
|
||||||
|
console.error('Unexpeced type for received data', data);
|
||||||
|
throw new Error('unexpected type for received data');
|
||||||
|
}
|
||||||
|
|
||||||
setFileStatus(
|
setFileStatus(
|
||||||
false, id, fileid, `Downloading... ${f.datalen}/${f.size}`, true,
|
false, id, fileid, `Downloading... ${f.datalen}/${f.size}`, true,
|
||||||
);
|
);
|
||||||
|
@ -2570,6 +2614,9 @@ function receiveFileData(id, fileid, f, dc, data) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dc.onmessage = null;
|
||||||
|
dc.onerror = null;
|
||||||
|
|
||||||
dc.send('done');
|
dc.send('done');
|
||||||
|
|
||||||
setFileStatus(false, id, fileid, 'Done.', true, true);
|
setFileStatus(false, id, fileid, 'Done.', true, true);
|
||||||
|
|
Loading…
Reference in a new issue