Search code examples
c++qtqwebviewqnetworkaccessmanagerqnetworkrequest

Request or AccessManager QT


In Google Chrome, when an error occurs in the request to the server, the Google Chrome tries a new request, see LOG wireshark: wireshark log

Note: This second attempt also ocorrre in Firefox and InternetExplorer. Note: WebInspector only appears in a request, in other words: The conventional browsers try new requests within a number of times or within a time.

I'm developing a full browser in QT and realized that if a request fails the "QWebView" has the same behavior as Google Chrome.

How can I reimplement the QNetWorkRequest/QNetWorkAccessManager to work like the conventional browsers?

Help me please.

myWebPage *myWP = new myWebPage();
myWP->setForwardUnsupportedContent(true);
myWP->setNetworkAccessManager(m_network);
ui->myWebView->setPage(myWP);

if(q!=true) {
    settings = QWebSettings::globalSettings();

    settings->setAttribute(QWebSettings::OfflineWebApplicationCacheEnabled,true);
    settings->setAttribute(QWebSettings::LocalContentCanAccessRemoteUrls,true);
    settings->setAttribute(QWebSettings::OfflineStorageDatabaseEnabled,true);
    settings->setAttribute(QWebSettings::LocalContentCanAccessFileUrls,true);
    settings->setAttribute(QWebSettings::LocalStorageEnabled,true);
    settings->setAttribute(QWebSettings::JavascriptCanOpenWindows,true);
    settings->setAttribute(QWebSettings::JavascriptCanCloseWindows,true);
    settings->setAttribute(QWebSettings::JavascriptEnabled,true);

    settings->setAttribute(QWebSettings::PluginsEnabled,true);
    settings->setAttribute(QWebSettings::JavaEnabled,false);//Disable java
    settings->setAttribute(QWebSettings::DeveloperExtrasEnabled,true);
    settings->setAttribute(QWebSettings::AutoLoadImages, true);


    settings->setAttribute(QWebSettings::DnsPrefetchEnabled, true);
    settings->setAttribute(QWebSettings::LocalStorageDatabaseEnabled, true);
    settings->setAttribute(QWebSettings::AcceleratedCompositingEnabled, true);
    settings->setAttribute(QWebSettings::JavascriptCanAccessClipboard, false);
    settings->setAttribute(QWebSettings::ScrollAnimatorEnabled, true);

    settings->setAttribute(QWebSettings::PrintElementBackgrounds, false);

    settings->setOfflineWebApplicationCachePath(QString(localStorage+"/appcache"));
    settings->enablePersistentStorage(QString(localStorage+"/persistent"));
    settings->setOfflineStoragePath(QString(localStorage+"/offlinestorage"));
    settings->setLocalStoragePath(QString(localStorage+"/storage"));
    settings->setIconDatabasePath(QString(localStorage+"/icons"));

    settings->setMaximumPagesInCache(99999);
    settings->setObjectCacheCapacities(0,99999,99999);

    settings->setOfflineWebApplicationCacheQuota(5*1024*1024);
    settings->setOfflineStorageDefaultQuota(5*1024*1024);
}
connect(ui->myWebView->page(), SIGNAL(downloadRequested(QNetworkRequest)), this, SLOT(Download(QNetworkRequest)));
connect(ui->myWebView->page(), SIGNAL(unsupportedContent(QNetworkReply*)), this, SLOT(unsupportedToDownload(QNetworkReply*)));
connect(ui->myWebView->page(), SIGNAL(printRequested(QWebFrame*)), this, SLOT(printFrame(QWebFrame*)));

Solution

  • I solved the problem:

    network.h

    #ifndef NETWORK_H
    #define NETWORK_H
    
    #include <QNetworkAccessManager>
    
    class netWork : public QNetworkAccessManager
    {
        Q_OBJECT
    
    protected:
        virtual QNetworkReply *createRequest(Operation op, const QNetworkRequest &request, QIODevice *outgoingData = 0);
    
    public:
        explicit netWork(QObject *parent = 0);
    };
    
    #endif // NETWORK_H
    

    network.cpp

    #include "network.h"
    #include <QNetworkReply>
    #include <QNetworkRequest>
    
    netWork::netWork(QObject *parent) :
        QNetworkAccessManager(parent)
    {
    }
    
    QNetworkReply * netWork::createRequest(Operation op, const QNetworkRequest &request, QIODevice *outgoingData){
        if(request.rawHeader("x-fixed-req")=="1") {//prevent infinite loop
            return QNetworkAccessManager::createRequest(op, request, outgoingData);
        }
        const QList<QByteArray>a = request.rawHeaderList();
    
        int j = a.length();
        int i=0;
    
        QNetworkRequest req(request.url());
        for(;i<j;++i){
            req.setRawHeader(a[i], request.rawHeader(a[i]));
        }
        req.setRawHeader("x-fixed-req", "1");
    
        QNetworkReply *p;
        if(op==PostOperation || op==PutOperation) {
            const QByteArray data = outgoingData->readAll();
    
            if(op==PostOperation) {
                p = this->post(req, data);
            } else {
                p = this->put(req, data);
            }
        } else if(op==DeleteOperation) {
            p = this->deleteResource(req);
        } else if(op==HeadOperation) {
            p = this->head(req);
        } else {
            p = this->get(req);
        }
    
        return p;
    }
    

    MainWindow.cpp (or something)

    #include "network.h";
    
    bool firstExec = false;
    QNetworkCookieJar *cookieJar;
    
    QNetworkDiskCache *m_cache;
    netWork *m_network = new netWork; //custom networkaccessmanager
    
    ...
    
    if(firstExec==false){
        firstExec = true;
        cookieJar = new QNetworkCookieJar;
    
        m_cache = new QNetworkDiskCache();
        m_cache->setCacheDirectory( QString("c:\\data") );
    
        m_network->setCache( m_cache );
        m_network->setCookieJar( cookieJar );
    
    }
    
    [QWEBVIEW]->setNetworkAccessManager( m_network );
    

    Note: To use cookies and cache, use the functions QNetworkAccessManager::setCookieJar and QNetworkAccessManager::setCache