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

Qt Quick application cannot retrieve images from 3G Network of some (not all) operators

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • P0: Blocker
    • None
    • 4.6.3, 4.7.3
    • None
    • Win 7 64 bits
      Qt SDK 11 Release
      Symbian^3 devices (N8, C7, E7)
    • b4028986a40406b077dfa14620a61ef718960a85, d65869a4a3bc76d2feecd039daa7f1e388e93433

    Description

      A basic Qt Quick application (see project NetworkIssue.zip enclosed) loading an image from network is systematically receiving the following message :
      << Error downloading http://www.lequipe.fr/Medias/Football/201104/650x475/les-quotidiens-espagnols-marca-et-as-ont-choisi-le-meme-titr.jpg - server replied:Forbidden >>

      How to reproduce :

      • Create a Qt Quick application using the wizard
      • Edit main.qml so it looks like this :
      import QtQuick 1.0
      
      Rectangle {
          width: 360
          height: 360
          Text {
              text: "Touch to quit"
              anchors.centerIn: parent
          }
      
          Image{
               id:newsImg
               width:100
               height:80
               source:"http://qt.nokia.com/logo.png"
            }
      
          MouseArea {
              anchors.fill: parent
              onClicked: {
                  Qt.quit();
              }
          }
      }
      
      • Insert a sim card of the given operator in your Symbian^3 device
      • Deactivate any wifi access point from your device to make sure you'll use operator IAP
      • Build and run the application on a Symbian^3 device
      • The image logo is not displayed

      Solution :

      The origin of the problem seems to be related to user agent filtering on operator network side : the default user agent used by http Qt stack is rejected by the network. The workaround solution consists in setting an explicit user agent (for instance the same user agent as the one used by Qt webkit). Here is how to fix it :

      1- define a helper class which inherits QWebPage as followed :

      class UserAgentProvider : public QWebPage {
          Q_OBJECT
      public:
          explicit UserAgentProvider(QWidget *parent = 0);
      
          QString getUserAgent()
          {
              return userAgentForUrl(QUrl(""));
          }
      };
      

      2- define a custom factory class which inherits QDeclarativeNetworkAccessManagerFactory as followed :

      class NetworkAccessManagerFactory : public QDeclarativeNetworkAccessManagerFactory
      {
      public:
          explicit NetworkAccessManagerFactory(QString p_userAgent = "");
      
          QNetworkAccessManager* create(QObject* parent)
          {
              CustomNetworkAccessManager* manager = new CustomNetworkAccessManager(__userAgent, parent);
              return manager;
          }
      
      private:
          QString __userAgent;
      };
      

      3- define a custom network class which inherits QNetworkAccessManager as followed :

      class CustomNetworkAccessManager : public QNetworkAccessManager {
          Q_OBJECT
      public:
          explicit CustomNetworkAccessManager(QString p_userAgent = "", QObject *parent = 0);
      
      protected:
          QNetworkReply *createRequest( Operation op, const QNetworkRequest &req, QIODevice * outgoingData=0 )
          {
              
              QNetworkRequest new_req(req);
              new_req.setRawHeader("User-Agent", __userAgent.toAscii());
      
              QNetworkReply *reply = QNetworkAccessManager::createRequest( op, new_req, outgoingData );
              return reply;
          }
      
      private:
          QString __userAgent;
      };
      

      4- modify main.cpp like this :

      // Set custom NetworkAccessManagerFactory object in QDeclarative context UserAgentProvider p; QString userAgent = p.getUserAgent();
      
      NetworkAccessManagerFactory factory(userAgent); viewer.engine()->setNetworkAccessManagerFactory(&factory); 
      
      

      Attached is a sample Qt project (NetworkOverload) which does the job.

      Note :
      The problem also occurs with pure Qt application (QML-less). The fix is slightly simple since subclassing QDeclarativeNetworkAccessManagerFactory is not required (step 2 and 4 can be removed).

      Attachments

        1. NetworkIssue.zip
          23 kB
        2. NetworkOverload.zip
          45 kB
        3. TestOviMap.zip
          44 kB
        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            epenttin Eero Penttinen
            nicolas.delabarre Nicolas Delabarre
            Votes:
            1 Vote for this issue
            Watchers:
            6 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes