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

QNetworkAccessCacheBackend ignores RedirectPolicyAttribute

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: P3: Somewhat important P3: Somewhat important
    • None
    • 6.4.2
    • None

      When a request is made with a CacheLoadControlAttribute value of AlwaysCache, the RedirectPolicyAttribute setting is ignored and seems to always revert back to ManualRedirectPolicy, even in Qt 6 where that's no longer the default.

      Here is a small reproducible example:

      #include <QtCore>
      #include <QtNetwork>
      
      int main(int argc, char *argv[])
      {
          QCoreApplication a(argc, argv);
      
          QNetworkAccessManager nam;
          QObject::connect(&nam, &QNetworkAccessManager::finished, &nam, [](QNetworkReply *reply) {
              QTextStream(stdout) << "Got a " << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() << " reply" << (reply->attribute(QNetworkRequest::SourceIsFromCacheAttribute).toBool() ? " from cache" : "") << ": " << reply->url().toDisplayString() << Qt::endl;
              reply->deleteLater();
          });
          auto cache = new QNetworkDiskCache;
          cache->setCacheDirectory("/tmp/qtcache");
          nam.setCache(cache);
          // For clarity -- this is the default value.
          nam.setRedirectPolicy(QNetworkRequest::NoLessSafeRedirectPolicy);
      
          QTextStream(stdout) << "Forcing a refresh: ";
          QNetworkRequest req1(QUrl("https://qt.io"));
          req1.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysNetwork);
          auto reply1 = nam.get(req1);
          QObject::connect(reply1, &QNetworkReply::finished, &a, [&]() {
              QTextStream(stdout) << "PreferCache: ";
              QNetworkRequest req2(QUrl("https://qt.io"));
              req2.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache);
              auto reply2 = nam.get(req2);
      
              QObject::connect(reply2, &QNetworkReply::finished, &a, [&]() {
                  QTextStream(stdout) << "AlwaysCache: ";
                  QNetworkRequest req3(QUrl("https://qt.io"));
                  req3.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysCache);
      
                  auto reply3 = nam.get(req3);
                  QObject::connect(reply3, &QNetworkReply::finished, &a, &QCoreApplication::quit);
              });
          });
      
          return a.exec();
      }
      

      Expected behavior

      There is a redirect from qt.io to www.qt.io which should always be followed, according to the NoLessSafeRedirectPolicy, so this code should print:

      Forcing a refresh: Got a 200 reply: https://www.qt.io/
      PreferCache: Got a 200 reply from cache: https://www.qt.io/
      AlwaysCache: Got a 200 reply from cache: https://www.qt.io/
      

      Actual behavior

      Running this code with Qt 6.4.2 (at least on my Archlinux machine) prints:

      Forcing a refresh: Got a 200 reply: https://www.qt.io/
      PreferCache: Got a 200 reply from cache: https://www.qt.io/
      AlwaysCache: Got a 301 reply from cache: https://qt.io
      

      When the CacheLoadControl is set to AlwaysCache, the qt.io → www.qt.io redirect is not followed, and we get a 301 reply. This would be the expected behavior with a ManualRedirectPolicy, but not with NoLessSafeRedirectPolicy.

      Additional information

      This seems related to QTBUG-40151 however that bug was related to QtWebKit and no longer applies to QWebEngine since it does not use QNetworkManager.

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

            manordheim Mårten Nordheim
            bclement Basile Clement
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:

                There are no open Gerrit changes