Fixed file upload to agent when websocket compression is used.
Ylian Saint-Hilaire committed
Jul 22, 2020 at 11:19 UTC
c1d702149815a398e390b1656332857c5b40856c
3 files changed
+21
-12
agents/meshcore.js
+13
-5
@@ -1219,8 +1219,8 @@ function createMeshCore(agent) {
1219
*/
1220
1221
// If there is a upload or download active on this connection, close the file
1222
- if (this.httprequest.uploadFile) { fs.closeSync(this.httprequest.uploadFile); this.httprequest.uploadFile = undefined; }
1223
- if (this.httprequest.downloadFile) { fs.closeSync(this.httprequest.downloadFile); this.httprequest.downloadFile = undefined; }
1222
+ if (this.httprequest.uploadFile) { fs.closeSync(this.httprequest.uploadFile); delete this.httprequest.uploadFile; }
1223
+ if (this.httprequest.downloadFile) { fs.closeSync(this.httprequest.downloadFile); delete this.httprequest.downloadFile; }
1224
1225
// Clean up WebRTC
1226
if (this.webrtc != null) {
@@ -1244,8 +1244,16 @@ function createMeshCore(agent) {
1244
// If this is upload data, save it to file
1245
if (this.httprequest.uploadFile) {
1246
if (typeof data == 'object') {
1247
- try { fs.writeSync(this.httprequest.uploadFile, data); } catch (e) { this.write(new Buffer(JSON.stringify({ action: 'uploaderror' }))); return; } // Write to the file, if there is a problem, error out.
1248
- this.write(new Buffer(JSON.stringify({ action: 'uploadack', reqid: this.httprequest.uploadFileid }))); // Ask for more data
1247
+ // Save the data to file being uploaded.
1248
+ if (this.httprequest.uploadFile) {
1249
+ try { fs.writeSync(this.httprequest.uploadFile, data); } catch (e) { sendConsoleText('FileSave ERROR'); this.write(new Buffer(JSON.stringify({ action: 'uploaderror' }))); return; } // Write to the file, if there is a problem, error out.
1250
+ this.write(new Buffer(JSON.stringify({ action: 'uploadack', reqid: this.httprequest.uploadFileid }))); // Ask for more data.
1251
+ }
1252
+ } else if (typeof data == 'string') {
1253
+ // Close the file and confirm. We need to make this added round trip since websocket deflate compression can cause the last message before a websocket close to not be received.
1254
+ if (this.httprequest.uploadFile) { fs.closeSync(this.httprequest.uploadFile); delete this.httprequest.uploadFile; }
1255
+ this.write(new Buffer(JSON.stringify({ action: 'uploaddone', reqid: this.httprequest.uploadFileid }))); // Indicate that we closed the file.
1256
+ this.end();
1257
}
1258
return;
1259
}
@@ -2044,7 +2052,7 @@ function createMeshCore(agent) {
2052
*/
2053
case 'upload': {
2054
// Upload a file, browser to agent
2047
- if (this.httprequest.uploadFile != undefined) { fs.closeSync(this.httprequest.uploadFile); this.httprequest.uploadFile = undefined; }
2055
+ if (this.httprequest.uploadFile != null) { fs.closeSync(this.httprequest.uploadFile); delete this.httprequest.uploadFile; }
2056
if (cmd.path == undefined) break;
2057
var filepath = cmd.name ? obj.path.join(cmd.path, cmd.name) : cmd.path;
2058
MeshServerLog('Upload: \"' + filepath + '\"', this.httprequest);
meshuser.js
+1
-1
@@ -785,7 +785,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
785
786
switch (cmd) {
787
case 'help': {
788
- var fin = '', f = '', availcommands = 'help,info,versions,args,resetserver,showconfig,usersessions,closeusersessions,tasklimiter,setmaxtasks,cores,migrationagents,agentstats,webstats,mpsstats,swarmstats,acceleratorsstats,updatecheck,serverupdate,nodeconfig,heapdump,relays,autobackup,backupconfig,dupagents,dispatchtable,badlogins,showpaths,le,lecheck,leevents,dbstats,sms,amtacm,certhashes,watchdog';
788
+ var fin = '', f = '', availcommands = 'help,info,versions,args,resetserver,usersessions,closeusersessions,tasklimiter,setmaxtasks,cores,migrationagents,agentstats,webstats,mpsstats,swarmstats,acceleratorsstats,updatecheck,serverupdate,nodeconfig,heapdump,relays,autobackup,backupconfig,dupagents,dispatchtable,badlogins,showpaths,le,lecheck,leevents,dbstats,sms,amtacm,certhashes,watchdog';
789
if (parent.parent.config.settings.heapdump === true) { availcommands += ',heapdump'; }
790
availcommands = availcommands.split(',').sort();
791
while (availcommands.length > 0) { if (f.length > 80) { fin += (f + ',\r\n'); f = ''; } f += (((f != '') ? ', ' : ' ') + availcommands.shift()); }
views/default.handlebars
+7
-6
@@ -7961,7 +7961,6 @@
7961
function p13uploadReconnect() {
7962
uploadFile.ws = CreateAgentRedirect(meshserver, CreateRemoteFiles(p13gotUploadData), serverPublicNamePort, authCookie, authRelayCookie, domainUrl);
7963
uploadFile.ws.attemptWebRTC = false;
7964
- uploadFile.ws.ctrlMsgAllowed = false;
7964
uploadFile.ws.onStateChanged = onFileUploadStateChange;
7965
uploadFile.ws.Start(filesNode._id);
7966
}
@@ -8016,6 +8015,9 @@
8015
for (var i = 0; i < 8; i++) { p13uploadNextPart(true); } // Send 8 more blocks of 4 k to full the websocket.
8016
} else if (cmd.action == 'uploadack') {
8017
p13uploadNextPart(false);
8018
+ } else if (cmd.action == 'uploaddone') {
8019
+ if (uploadFile.ws != null) { uploadFile.ws.Stop(); uploadFile.ws = null; }
8020
+ if (uploadFile.xfiles.length > uploadFile.xfilePtr + 1) { p13uploadReconnect(); } else { p13uploadFileCancel(); }
8021
} else if (cmd.action == 'uploaderror') {
8022
p13uploadFileCancel();
8023
}
@@ -8025,12 +8027,11 @@
8027
function p13uploadNextPart(dataPriming) {
8028
var data = uploadFile.xdata;
8029
var start = uploadFile.xptr;
8028
- var end = uploadFile.xptr + 4096;
8029
- if (end > data.byteLength) { if (dataPriming == true) { return; } end = data.byteLength; }
8030
- if (start == data.byteLength) {
8031
- if (uploadFile.ws != null) { uploadFile.ws.Stop(); uploadFile.ws = null; }
8032
- if (uploadFile.xfiles.length > uploadFile.xfilePtr + 1) { p13uploadReconnect(); } else { p13uploadFileCancel(); }
8030
+ if (start >= data.byteLength) {
8031
+ uploadFile.ws.sendCtrlMsg('{"ctrlChannel":"102938","type":"close"}');
8032
} else {
8033
+ var end = uploadFile.xptr + 16384;
8034
+ if (end > data.byteLength) { if (dataPriming == true) { return; } end = data.byteLength; }
8035
var datapart = data.slice(start, end);
8036
uploadFile.ws.send(datapart);
8037
uploadFile.xptr = end;