From 8dddc03e5945f882a161b0683e9b9e57ed0463df Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Sun, 20 Jan 2019 16:20:36 -0800 Subject: [PATCH 1/4] In receive mode, only tell the GUI that a new request is coming in if it contains files --- onionshare/web/receive_mode.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/onionshare/web/receive_mode.py b/onionshare/web/receive_mode.py index 2b4e8faf..c319ce13 100644 --- a/onionshare/web/receive_mode.py +++ b/onionshare/web/receive_mode.py @@ -275,11 +275,8 @@ class ReceiveModeRequest(Request): strings._("receive_mode_upload_starting").format(self.web.common.human_readable_filesize(self.content_length)) )) - # Tell the GUI - self.web.add_request(self.web.REQUEST_STARTED, self.path, { - 'id': self.upload_id, - 'content_length': self.content_length - }) + # Don't tell the GUI that a request has started until we start receiving files + self.told_gui_about_request = False self.web.receive_mode.uploads_in_progress.append(self.upload_id) @@ -291,6 +288,14 @@ class ReceiveModeRequest(Request): writable stream. """ if self.upload_request: + if not self.told_gui_about_request: + # Tell the GUI about the request + self.web.add_request(self.web.REQUEST_STARTED, self.path, { + 'id': self.upload_id, + 'content_length': self.content_length + }) + self.told_gui_about_request = True + self.progress[filename] = { 'uploaded_bytes': 0, 'complete': False From db07920acab6212023ac245fab7964277193f706 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Sun, 20 Jan 2019 16:34:56 -0800 Subject: [PATCH 2/4] Skip updating or canceling items that haven't been added --- onionshare_gui/mode/history.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/onionshare_gui/mode/history.py b/onionshare_gui/mode/history.py index bb419ec7..b54b6f5f 100644 --- a/onionshare_gui/mode/history.py +++ b/onionshare_gui/mode/history.py @@ -355,13 +355,15 @@ class HistoryItemList(QtWidgets.QScrollArea): """ Update an item. Override this method. """ - self.items[id].update(data) + if id in self.items: + self.items[id].update(data) def cancel(self, id): """ Cancel an item. Override this method. """ - self.items[id].cancel() + if id in self.items: + self.items[id].cancel() def reset(self): """ From a658b65140ca3fe9b8e73cfba18410a75684539c Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Mon, 21 Jan 2019 11:16:55 -0800 Subject: [PATCH 3/4] Don't update the GUI at all untless it has been told about the request --- onionshare/web/receive_mode.py | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/onionshare/web/receive_mode.py b/onionshare/web/receive_mode.py index c319ce13..5e332a39 100644 --- a/onionshare/web/receive_mode.py +++ b/onionshare/web/receive_mode.py @@ -278,8 +278,6 @@ class ReceiveModeRequest(Request): # Don't tell the GUI that a request has started until we start receiving files self.told_gui_about_request = False - self.web.receive_mode.uploads_in_progress.append(self.upload_id) - self.previous_file = None def _get_file_stream(self, total_content_length, content_type, filename=None, content_length=None): @@ -294,6 +292,8 @@ class ReceiveModeRequest(Request): 'id': self.upload_id, 'content_length': self.content_length }) + self.web.receive_mode.uploads_in_progress.append(self.upload_id) + self.told_gui_about_request = True self.progress[filename] = { @@ -309,12 +309,13 @@ class ReceiveModeRequest(Request): """ super(ReceiveModeRequest, self).close() try: - upload_id = self.upload_id - # Inform the GUI that the upload has finished - self.web.add_request(self.web.REQUEST_UPLOAD_FINISHED, self.path, { - 'id': upload_id - }) - self.web.receive_mode.uploads_in_progress.remove(upload_id) + if self.told_gui_about_request: + upload_id = self.upload_id + # Inform the GUI that the upload has finished + self.web.add_request(self.web.REQUEST_UPLOAD_FINISHED, self.path, { + 'id': upload_id + }) + self.web.receive_mode.uploads_in_progress.remove(upload_id) except AttributeError: pass @@ -336,10 +337,11 @@ class ReceiveModeRequest(Request): ), end='') # Update the GUI on the upload progress - self.web.add_request(self.web.REQUEST_PROGRESS, self.path, { - 'id': self.upload_id, - 'progress': self.progress - }) + if self.told_gui_about_request: + self.web.add_request(self.web.REQUEST_PROGRESS, self.path, { + 'id': self.upload_id, + 'progress': self.progress + }) def file_close_func(self, filename): """ From d68db75c6859a43de65f51687e04e32b36307812 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Mon, 21 Jan 2019 17:11:58 -0800 Subject: [PATCH 4/4] Write test to confirm that submitting the receive mode form without selecting files doesn't change in_progress_count or completed_count --- onionshare/web/receive_mode.py | 2 +- tests/GuiReceiveTest.py | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/onionshare/web/receive_mode.py b/onionshare/web/receive_mode.py index 5e332a39..30414b77 100644 --- a/onionshare/web/receive_mode.py +++ b/onionshare/web/receive_mode.py @@ -67,7 +67,7 @@ class ReceiveModeWeb(object): receive_mode_dir = os.path.join(self.common.settings.get('data_dir'), date_dir, time_dir) valid = True try: - os.makedirs(receive_mode_dir, 0o700) + os.makedirs(receive_mode_dir, 0o700, exist_ok=True) except PermissionError: self.web.add_request(self.web.REQUEST_ERROR_DATA_DIR_CANNOT_CREATE, request.path, { "receive_mode_dir": receive_mode_dir diff --git a/tests/GuiReceiveTest.py b/tests/GuiReceiveTest.py index a23a4bc6..8a03283e 100644 --- a/tests/GuiReceiveTest.py +++ b/tests/GuiReceiveTest.py @@ -52,6 +52,28 @@ class GuiReceiveTest(GuiBaseTest): response = requests.get('http://127.0.0.1:{}/close'.format(self.gui.app.port)) self.assertEqual(response.status_code, 404) + def uploading_zero_files_shouldnt_change_ui(self, mode, public_mode): + '''If you submit the receive mode form without selecting any files, the UI shouldn't get updated''' + if not public_mode: + path = 'http://127.0.0.1:{}/{}/upload'.format(self.gui.app.port, self.gui.receive_mode.web.slug) + else: + path = 'http://127.0.0.1:{}/upload'.format(self.gui.app.port) + + # What were the counts before submitting the form? + before_in_progress_count = mode.history.in_progress_count + before_completed_count = mode.history.completed_count + before_number_of_history_items = len(mode.history.item_list.items) + + # Click submit without including any files a few times + response = requests.post(path, files={}) + response = requests.post(path, files={}) + response = requests.post(path, files={}) + + # The counts shouldn't change + self.assertEqual(mode.history.in_progress_count, before_in_progress_count) + self.assertEqual(mode.history.completed_count, before_completed_count) + self.assertEqual(len(mode.history.item_list.items), before_number_of_history_items) + def run_receive_mode_sender_closed_tests(self, public_mode): '''Test that the share can be stopped by the sender in receive mode''' if not public_mode: @@ -97,6 +119,7 @@ class GuiReceiveTest(GuiBaseTest): self.counter_incremented(self.gui.receive_mode, 3) self.upload_file(public_mode, '/tmp/testdir/test', 'test') self.counter_incremented(self.gui.receive_mode, 4) + self.uploading_zero_files_shouldnt_change_ui(self.gui.receive_mode, public_mode) self.history_indicator(self.gui.receive_mode, public_mode) self.server_is_stopped(self.gui.receive_mode, False) self.web_server_is_stopped()