-
Bug
-
Resolution: Unresolved
-
Not Evaluated
-
None
-
6.9.2, 6.9.3
-
None
When using QWebEngineUrlRequestInfo::redirect() the redirect can fail without being processed because of CORS. This does not happen with Qt 6.8
The bug seems to occurs when the following steps are done:
- Load a page from foo.com
- The page attempts to load a script from bar.com
- The request to load the script is intercepted and redirected to foo.com
- The request to load the script from foo.com is intercepted, but continues without change
- The script loaded from foo.com attempts to load a resource from bar.com
- The request to load the resource from bar.com is intercepted and redirected to foo.com
- The request fails because "bar.com did not send the Access-Control-Allow-Origin header", no redirection or further request happens.
The can be reproduce by adding the following unit test to tst_QWebEngineUrlRequestInterceptor:
void tst_QWebEngineUrlRequestInterceptor::redirect() { HttpServer server; server.setResourceDirs(\{ ":/resources" }); QVERIFY(server.start()); TestRequestInterceptor interceptor; interceptor.onIntercept = [&](QWebEngineUrlRequestInfo &info) { const auto url = server.url(info.requestUrl().path()); if (info.requestUrl() != url) { qDebug() << "FROM" << info.requestUrl() << "TO" << url; info.redirect(url); return false; } return true; }; QWebEnginePage page; page.setUrlRequestInterceptor(&interceptor); QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool))); const auto url = QUrl(server.url("/cors.html")); page.load(url); QTRY_COMPARE(loadSpy.size(), 1); // We expect 3 requests: cors.html, cors.js and content.html // redirected requests are not counted // We will only get 2 because the request to fetch content.html will never happen QCOMPARE(interceptor.requestInfos.size(), 3); }
cors.html
<html> <head><link rel="icon" href="data:,"></head> <script src="http://www.qt.io/cors.js"></script>> <body> </body> </html>
cors.js
async function getData() { const url = "https://qt.io/content.html"; try { const response = await fetch(url); if (!response.ok) { throw new Error(`Response status: ${response.status}`); } const result = await response.json(); console.log(result); } catch (error) { console.error(error.message); } } getData();
which fives the following output:
15:41:48: Starting tst_qwebengineurlrequestinterceptor redirect... ********* Start testing of tst_QWebEngineUrlRequestInterceptor ********* Config: Using QtTest library 6.9.3, Qt 6.9.3 (x86_64-little_endian-lp64 shared (dynamic) debug build; by Ubuntu Clang 19.1.1 (1ubuntu1~24.04.2)), ubuntu 24.04 PASS : tst_QWebEngineUrlRequestInterceptor::initTestCase() QINFO : tst_QWebEngineUrlRequestInterceptor::redirect() HttpServer: GET /cors.html 200 212 QDEBUG : tst_QWebEngineUrlRequestInterceptor::redirect() FROM QUrl("http://www.qt.io/cors.js") TO QUrl("http://127.0.0.1:46423/cors.js") QINFO : tst_QWebEngineUrlRequestInterceptor::redirect() HttpServer: GET /cors.js 200 352 QDEBUG : tst_QWebEngineUrlRequestInterceptor::redirect() FROM QUrl("https://qt.io/content.html") TO QUrl("http://127.0.0.1:46423/content.html") QCRITICAL: tst_QWebEngineUrlRequestInterceptor::redirect() js: Access to fetch at 'https://qt.io/content.html' from origin 'http://127.0.0.1:46423' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled. QCRITICAL: tst_QWebEngineUrlRequestInterceptor::redirect() js: Uncaught (in promise) ReferenceError: br is not defined FAIL! : tst_QWebEngineUrlRequestInterceptor::redirect() Compared values are not the same Actual (interceptor.requestInfos.size()): 2 Expected (3) : 3 Loc: [qt5/qtwebengine/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp(1171)] PASS : tst_QWebEngineUrlRequestInterceptor::cleanupTestCase() Totals: 2 passed, 1 failed, 0 skipped, 0 blacklisted, 420ms ********* Finished testing of tst_QWebEngineUrlRequestInterceptor *********