Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-140889

QWebEngineUrlRequestInfo::redirect() fails with No 'Access-Control-Allow-Origin' header is present on the requested resource.

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Not Evaluated Not Evaluated
    • None
    • 6.9.2, 6.9.3
    • WebEngine
    • None
    • Linux/X11

      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:

      1. Load a page from foo.com
      2. The page attempts to load a script from bar.com
      3. The request to load the script is intercepted and redirected to foo.com
      4. The request to load the script from foo.com is intercepted, but continues without change
      5. The script loaded from foo.com attempts to load a resource from bar.com
      6. The request to load the resource from bar.com is intercepted and redirected to foo.com
      7. 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 *********
      

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

            qt_webengine_team Qt WebEngine Team
            bterrier Benjamin Terrier
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:

                There are no open Gerrit changes