From ebc70f66e5e4b671ee6b4d975339e253a0a1ea2c Mon Sep 17 00:00:00 2001 From: Daniel Schadt Date: Tue, 21 Mar 2017 18:54:21 +0100 Subject: [PATCH 1/2] Check for None-reply in _do_die Fixes #2304 In some cases, the finished handler fired before the error handler, e.g. when downloading a 500 error page that is sent as attachment: HTTP/1.1 500 Internal Server Error Content-Type: application/octet-stream Content-Disposition: inline; filename="attachment.jpg" here we downloaded 0 bytes, fired the finished handler and after that fired the error handler because of the 500 - but the finished handler had already set our reply to None (and displayed the error message). --- qutebrowser/browser/qtnetworkdownloads.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/qutebrowser/browser/qtnetworkdownloads.py b/qutebrowser/browser/qtnetworkdownloads.py index 5ac689e29..920673d4b 100644 --- a/qutebrowser/browser/qtnetworkdownloads.py +++ b/qutebrowser/browser/qtnetworkdownloads.py @@ -110,6 +110,9 @@ class DownloadItem(downloads.AbstractDownloadItem): def _do_die(self): """Abort the download and emit an error.""" self._read_timer.stop() + if self._reply is None: + log.downloads.debug("Reply gone while dying") + return self._reply.downloadProgress.disconnect() self._reply.finished.disconnect() self._reply.error.disconnect() From 631936361405d812f353b4108246c883cdf48100 Mon Sep 17 00:00:00 2001 From: Daniel Schadt Date: Wed, 22 Mar 2017 13:38:03 +0100 Subject: [PATCH 2/2] add a test for downloading a 500 inline attachment --- tests/end2end/features/downloads.feature | 6 ++++++ tests/end2end/fixtures/webserver.py | 2 ++ tests/end2end/fixtures/webserver_sub.py | 11 +++++++++++ 3 files changed, 19 insertions(+) diff --git a/tests/end2end/features/downloads.feature b/tests/end2end/features/downloads.feature index cb198e09d..444cf8721 100644 --- a/tests/end2end/features/downloads.feature +++ b/tests/end2end/features/downloads.feature @@ -611,3 +611,9 @@ Feature: Downloading things from a website. And I run :follow-hint 0 And I wait until the download is finished Then the downloaded file user-agent should contain Safari/ + + @qtwebengine_skip: Handled by QtWebEngine, not by us + Scenario: Downloading a "Internal server error" with disposition: inline (#2304) + When I set storage -> prompt-download-directory to false + And I open custom/500-inline + Then the error "Download error: *INTERNAL SERVER ERROR" should be shown diff --git a/tests/end2end/fixtures/webserver.py b/tests/end2end/fixtures/webserver.py index f6e0f8ff2..c43765bf6 100644 --- a/tests/end2end/fixtures/webserver.py +++ b/tests/end2end/fixtures/webserver.py @@ -74,6 +74,8 @@ class Request(testprocess.Line): '/redirect-to': [http.client.FOUND], '/cookies/set': [http.client.FOUND], + + '/custom/500-inline': [http.client.INTERNAL_SERVER_ERROR], } for i in range(15): path_to_statuses['/redirect/{}'.format(i)] = [http.client.FOUND] diff --git a/tests/end2end/fixtures/webserver_sub.py b/tests/end2end/fixtures/webserver_sub.py index df84d26d6..51a03e0b5 100644 --- a/tests/end2end/fixtures/webserver_sub.py +++ b/tests/end2end/fixtures/webserver_sub.py @@ -122,6 +122,17 @@ def redirect_self(): return app.make_response(flask.redirect(flask.url_for('redirect_self'))) +@app.route('/custom/500-inline') +def internal_error_attachment(): + """A 500 error with Content-Disposition: inline.""" + response = flask.Response(b"", headers={ + "Content-Type": "application/octet-stream", + "Content-Disposition": 'inline; filename="attachment.jpg"', + }) + response.status_code = 500 + return response + + @app.after_request def log_request(response): """Log a webserver request."""