1
Fork 0
mirror of https://github.com/jech/galene.git synced 2024-11-24 17:45:58 +01:00

Add versioning to file transfer protocol.

This commit is contained in:
Juliusz Chroboczek 2024-11-02 13:36:09 +01:00
parent 1745b6294e
commit d85a6ea203

View file

@ -1611,6 +1611,16 @@ function TransferredFile(sc, userid, id, up, username, name, mimetype, size) {
* @type {string} * @type {string}
*/ */
this.id = id; this.id = id;
/**
* The negotiated file-transfer protocol version.
*
* This is the version of the file-transfer protocol, and is not
* necessarily equal to the version of the Galene protocol used by the
* server connection.
*
* @type {string}
*/
this.version = null;
/** /**
* True if this is an upload. * True if this is an upload.
* *
@ -1797,6 +1807,26 @@ TransferredFile.prototype.event = function(state, data) {
f.onevent.call(f, state, data); f.onevent.call(f, state, data);
} }
/**
* Send a cancel message for a file transfer.
*
* Don't call this, call TransferredFile.cancel instead.
*
* @param {ServerConnection} sc
* @param {string} userid
* @param {string} id
* @param {string|Error} [message]
*/
function sendFileCancel(sc, userid, id, message) {
let m = {
type: 'cancel',
id: id,
};
if(message)
m.message = message.toString();
sc.userMessage('filetransfer', userid, m);
}
/** /**
* Cancel a file transfer. * Cancel a file transfer.
@ -1804,23 +1834,16 @@ TransferredFile.prototype.event = function(state, data) {
* Depending on the state, this will either forcibly close the connection, * Depending on the state, this will either forcibly close the connection,
* send a handshake, or do nothing. It will set the state to cancelled. * send a handshake, or do nothing. It will set the state to cancelled.
* *
* @param {string|Error} [data] * @param {string|Error} [message]
*/ */
TransferredFile.prototype.cancel = function(data) { TransferredFile.prototype.cancel = function(message) {
let f = this; let f = this;
if(f.state === 'closed') if(f.state === 'closed')
return; return;
if(f.state !== '' && f.state !== 'done' && f.state !== 'cancelled') { if(f.state !== '' && f.state !== 'done' && f.state !== 'cancelled')
let m = { sendFileCancel(f.sc, f.userid, f.id, message);
type: 'cancel',
id: f.id,
};
if(data)
m.message = data.toString();
f.sc.userMessage('filetransfer', f.userid, m);
}
if(f.state !== 'done' && f.state !== 'cancelled') if(f.state !== 'done' && f.state !== 'cancelled')
f.event('cancelled', data); f.event('cancelled', message);
f.close(); f.close();
} }
@ -1878,6 +1901,7 @@ ServerConnection.prototype.sendFile = function(id, file) {
sc.transferredFiles[f.fullid()] = f; sc.transferredFiles[f.fullid()] = f;
sc.userMessage('filetransfer', id, { sc.userMessage('filetransfer', id, {
type: 'invite', type: 'invite',
version: ["1"],
id: fileid, id: fileid,
name: f.name, name: f.name,
size: f.size, size: f.size,
@ -1944,6 +1968,7 @@ TransferredFile.prototype.receive = async function() {
await pc.setLocalDescription(offer); await pc.setLocalDescription(offer);
f.sc.userMessage('filetransfer', f.userid, { f.sc.userMessage('filetransfer', f.userid, {
type: 'offer', type: 'offer',
version: [f.version],
id: f.id, id: f.id,
sdp: pc.localDescription.sdp, sdp: pc.localDescription.sdp,
}); });
@ -2163,10 +2188,21 @@ ServerConnection.prototype.fileTransfer = function(id, username, message) {
let sc = this; let sc = this;
switch(message.type) { switch(message.type) {
case 'invite': { case 'invite': {
/** @type {string} */
let version;
if((message.version instanceof Array) && message.version.includes('1')) {
version = '1';
} else {
sendFileCancel(sc, id, message.id,
`Unknown protocol version ${message.version}; ` +
'perhaps you need to upgrade your client ?');
return;
}
let f = new TransferredFile( let f = new TransferredFile(
sc, id, message.id, false, username, sc, id, message.id, false, username,
message.name, message.mimetype, message.size, message.name, message.mimetype, message.size,
); );
f.version = version;
f.state = 'inviting'; f.state = 'inviting';
try { try {
@ -2194,17 +2230,30 @@ ServerConnection.prototype.fileTransfer = function(id, username, message) {
sc.transferredFiles[fid] = f; sc.transferredFiles[fid] = f;
break; break;
} }
case 'offer': case 'offer': {
let f = sc.getTransferredFile(id, message.id);
if(!f) {
console.error(`Unexpected ${message.type} for file transfer`);
return;
}
if((message.version instanceof Array) && message.version.includes('1')) {
f.version = '1';
} else {
f.cancel(`Unknown protocol version ${message.version}; ` +
'perhaps you need to upgrade your client ?'
);
return;
}
f.answer(message.sdp).catch(e => f.cancel(e));
break;
}
case 'answer': { case 'answer': {
let f = sc.getTransferredFile(id, message.id); let f = sc.getTransferredFile(id, message.id);
if(!f) { if(!f) {
console.error(`Unexpected ${message.type} for file transfer`); console.error(`Unexpected ${message.type} for file transfer`);
return; return;
} }
if(message.type === 'offer') f.receiveFile(message.sdp).catch(e => f.cancel(e));
f.answer(message.sdp).catch(e => f.cancel(e));
else
f.receiveFile(message.sdp).catch(e => f.cancel(e));
break; break;
} }
case 'ice': case 'ice':
@ -2226,7 +2275,7 @@ ServerConnection.prototype.fileTransfer = function(id, username, message) {
console.error(`Unexpected ${message.type} for file transfer`); console.error(`Unexpected ${message.type} for file transfer`);
return; return;
} }
f.event('cancelled', message.value || null); f.event('cancelled', message.message || null);
f.close(); f.close();
break; break;
} }