diff options
author | Florian Bruhin <me@the-compiler.org> | 2020-12-30 20:59:59 +0100 |
---|---|---|
committer | Florian Bruhin <me@the-compiler.org> | 2020-12-30 20:59:59 +0100 |
commit | fee09462965e8f19f067a467f85b00cd362ddff6 (patch) | |
tree | 44deafed92c383e8fee770b137012d65317004e8 | |
parent | 7a048f5cd8edf376434aa5d11461982b5ae50dcb (diff) | |
download | qutebrowser-fee09462965e8f19f067a467f85b00cd362ddff6.tar.gz qutebrowser-fee09462965e8f19f067a467f85b00cd362ddff6.zip |
Don't override XHR Accept header
Fixes #5998
-rw-r--r-- | doc/changelog.asciidoc | 4 | ||||
-rw-r--r-- | qutebrowser/browser/webengine/interceptor.py | 14 | ||||
-rw-r--r-- | tests/end2end/data/misc/xhr_headers.html | 29 | ||||
-rw-r--r-- | tests/end2end/features/conftest.py | 3 | ||||
-rw-r--r-- | tests/end2end/features/misc.feature | 13 |
5 files changed, 60 insertions, 3 deletions
diff --git a/doc/changelog.asciidoc b/doc/changelog.asciidoc index 5bd8778f7..5001db304 100644 --- a/doc/changelog.asciidoc +++ b/doc/changelog.asciidoc @@ -122,6 +122,10 @@ Changed * `content.host_blocking.enabled` -> `content.blocking.enabled` (controlling both blockers) * `content.host_blocking.whitelist` -> `content.blocking.whitelist` (controlling both blockers) * `content.host_blocking.lists` -> `content.blocking.hosts.lists` +- With the (default) QtWebEngine backend, if a custom `accept` header is set via + `content.headers.custom`, the custom value is now ignored for XHR + (`XMLHttpRequest`) requests. Instead, the sent value is now `*/*` or the header + set from JavaScript, as it would be if `content.headers.custom` wasn't set. Fixed ~~~~~ diff --git a/qutebrowser/browser/webengine/interceptor.py b/qutebrowser/browser/webengine/interceptor.py index 54bc5623b..8804bea6e 100644 --- a/qutebrowser/browser/webengine/interceptor.py +++ b/qutebrowser/browser/webengine/interceptor.py @@ -177,11 +177,11 @@ class RequestInterceptor(QWebEngineUrlRequestInterceptor): info.resourceType()))) resource_type = interceptors.ResourceType.unknown + is_xhr = info.resourceType() == QWebEngineUrlRequestInfo.ResourceTypeXhr + if ((url.scheme(), url.host(), url.path()) == ('qute', 'settings', '/set')): - if (first_party != QUrl('qute://settings/') or - info.resourceType() != - QWebEngineUrlRequestInfo.ResourceTypeXhr): + if first_party != QUrl('qute://settings/') or not is_xhr: log.network.warning("Blocking malicious request from {} to {}" .format(first_party.toDisplayString(), url.toDisplayString())) @@ -200,6 +200,14 @@ class RequestInterceptor(QWebEngineUrlRequestInterceptor): info.block(True) for header, value in shared.custom_headers(url=url): + if header.lower() == b'accept' and is_xhr: + # https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/setRequestHeader + # says: "If no Accept header has been set using this, an Accept header + # with the type "*/*" is sent with the request when send() is called." + # + # We shouldn't break that if someone sets a custom Accept header for + # normal requests. + continue info.setHttpHeader(header, value) # Note this is ignored before Qt 5.12.4 and 5.13.1 due to diff --git a/tests/end2end/data/misc/xhr_headers.html b/tests/end2end/data/misc/xhr_headers.html new file mode 100644 index 000000000..eda129e68 --- /dev/null +++ b/tests/end2end/data/misc/xhr_headers.html @@ -0,0 +1,29 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>XHR headers test</title> + <script> + function xhr_headers() { + const xhr = new XMLHttpRequest(); + xhr.open("GET", "/headers"); + xhr.setRequestHeader("X-Qute-Test", "from XHR"); + + const elem = document.getElementById("output"); + xhr.addEventListener("load", function(event) { + if (xhr.status == 200) { + elem.textContent = xhr.responseText; + console.log("Got headers via XHR") + } else { + elem.textContent = xhr.statusText; + console.warn(xhr.statusText, xhr.responseText); + } + }); + xhr.send(); + } + </script> + </head> + <body onload="xhr_headers()"> + <pre id="output">unknown</pre> + </body> +</html> diff --git a/tests/end2end/features/conftest.py b/tests/end2end/features/conftest.py index 87748a43a..65f934d9f 100644 --- a/tests/end2end/features/conftest.py +++ b/tests/end2end/features/conftest.py @@ -562,6 +562,9 @@ def check_header(quteproc, header, value): print(data) if value == '<unset>': assert header not in data['headers'] + elif value.startswith("'") and value.endswith("'"): # literal match + actual = data['headers'][header] + assert actual == value[1:-1] else: actual = data['headers'][header] assert testutils.pattern_match(pattern=value, value=actual) diff --git a/tests/end2end/features/misc.feature b/tests/end2end/features/misc.feature index 570bd3321..584101e6d 100644 --- a/tests/end2end/features/misc.feature +++ b/tests/end2end/features/misc.feature @@ -325,6 +325,11 @@ Feature: Various utility commands. And I open headers Then the header X-Qute-Test should be set to testvalue + Scenario: Setting accept header + When I set content.headers.custom to {"Accept": "testvalue"} + And I open headers + Then the header Accept should be set to testvalue + Scenario: DNT header When I set content.headers.do_not_track to true And I open headers @@ -366,6 +371,14 @@ Feature: Various utility commands. And I run :jseval console.log(window.navigator.userAgent) Then the javascript message "toaster" should be logged + @qtwebkit_skip + Scenario: Custom headers via XHR + When I set content.headers.custom to {"Accept": "config-value", "X-Qute-Test": "config-value"} + And I open data/misc/xhr_headers.html + And I wait for the javascript message "Got headers via XHR" + Then the header Accept should be set to '*/*' + And the header X-Qute-Test should be set to config-value + ## https://github.com/qutebrowser/qutebrowser/issues/1523 Scenario: Completing a single option argument |