From ab5e20d1cdd6946775d0a821786871f248c9e7f0 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Mon, 30 Oct 2017 17:11:22 +0100 Subject: [PATCH] Fix folder upload race condition When uploading the same folder twice, sometimes a race condition is triggered where some of the first uploaded items finish faster and trigger the "end of transfer" event even though there are further items to upload. This fix prevents the end of transfer event to clear the list of uploads so it can continue. --- apps/files/js/file-upload.js | 16 +++++++++++----- apps/files/js/upload.js | 18 ------------------ apps/files/tests/js/fileUploadSpec.js | 10 ++++++++++ 3 files changed, 21 insertions(+), 23 deletions(-) delete mode 100644 apps/files/js/upload.js diff --git a/apps/files/js/file-upload.js b/apps/files/js/file-upload.js index eb57101f07d7..23f1deb0a47f 100644 --- a/apps/files/js/file-upload.js +++ b/apps/files/js/file-upload.js @@ -37,12 +37,11 @@ OC.FileUpload = function(uploader, data) { if (!data) { throw 'Missing "data" argument in OC.FileUpload constructor'; } - var path = ''; + var basePath = ''; if (this.uploader.fileList) { - path = OC.joinPaths(this.uploader.fileList.getCurrentDirectory(), this.getFile().name); - } else { - path = this.getFile().name; + basePath = this.uploader.fileList.getCurrentDirectory(); } + var path = OC.joinPaths(basePath, this.getFile().relativePath || '', this.getFile().name); this.id = 'web-file-upload-' + md5(path) + '-' + (new Date()).getTime(); }; OC.FileUpload.CONFLICT_MODE_DETECT = 0; @@ -622,7 +621,13 @@ OC.Uploader.prototype = _.extend({ * Clear uploads */ clear: function() { - this._uploads = {}; + var remainingUploads = {}; + _.each(this._uploads, function(upload, key) { + if (!upload.isDone) { + remainingUploads[key] = upload; + } + }); + this._uploads = remainingUploads; this._knownDirs = {}; }, /** @@ -1092,6 +1097,7 @@ OC.Uploader.prototype = _.extend({ var upload = self.getUpload(data); var that = $(this); self.log('done', e, upload); + upload.isDone = true; var status = upload.getResponseStatus(); if (status < 200 || status >= 300) { diff --git a/apps/files/js/upload.js b/apps/files/js/upload.js deleted file mode 100644 index 518608615e06..000000000000 --- a/apps/files/js/upload.js +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (c) 2014 - * - * This file is licensed under the Affero General Public License version 3 - * or later. - * - * See the COPYING-README file. - * - */ - -function Upload(fileSelector) { - if ($.support.xhrFileUpload) { - return new XHRUpload(fileSelector.target.files); - } else { - return new FormUpload(fileSelector); - } -} -Upload.target = OC.filePath('files', 'ajax', 'upload.php'); diff --git a/apps/files/tests/js/fileUploadSpec.js b/apps/files/tests/js/fileUploadSpec.js index 946ac2a8cc45..82c6b6ca7b51 100644 --- a/apps/files/tests/js/fileUploadSpec.js +++ b/apps/files/tests/js/fileUploadSpec.js @@ -119,6 +119,16 @@ describe('OC.Upload tests', function() { expect(upload).toBeDefined(); expect(upload.getFileName()).toEqual('test.txt'); }); + it('clear leaves pending uploads', function() { + uploader._uploads = { + 'abc': {name: 'a job well done.txt', isDone: true}, + 'def': {name: 'whatevs.txt'} + }; + + uploader.clear(); + + expect(uploader._uploads).toEqual({'def': {name: 'whatevs.txt'}}); + }); }); describe('Upload conflicts', function() { var conflictDialogStub;