need to peek QnewtworkReply before WebView read it



  • Hope someone helps me


  • Moderators

    @6ygyjiau
    are you using QtWebEnigne or QtWebkit?



  • QtWebKit


  • Moderators

    @6ygyjiau
    then you can do the following:

    1. create a custom QNetworkAccessManager and reimplement createRequest()
    2. In there call the base class implementation and connect to the returned QNetworkReply (this guarantees you that you receive the finished signal before QtWebkit does)
    3. return the QNetworkReply (to QtWebkit)
    4. set a new instance of your custom QNetworkAccessManager to QtWebkit (QWebPage::setNetworkAccessManager())


  • @raven-worx can you explain 2 and 3 step


  • Moderators

    @6ygyjiau

    QNetworkReply* MyNetworkAccessManager::createRequest(Operation op, const QNetworkRequest & req, QIODevice * outgoingData)
    {
         QNetworkReply* reply = QNetworkAccessManager::createRequest(op,req,outgoingData);
         connect( reply, &QNetworkReply::finished, this, &MyNetworkAccessManager::mySlot ); // ensures that you are the first who receives the finished signal
         return reply;
    }
    

    But maybe you should tell what you are trying to achieve, maybe this approach isn't suitable.



  • I have a lot of replies and I tried to connect to MyNetworkAccessManager::finished(QNetworkReply*) , but replies already readed by WebView .


  • Moderators

    @6ygyjiau
    ok, try connecting to the QNetworkAccessManager::finished(QNetworkReply*) signal in the constrcutor of your custom network access manager.



  • the same result as connect MyNetworkAccessManager::finished(QNetworkReply*)



  • Its late. But I solved it with custom QNetworkReply

    NetworkReply.h################################################################

    #include <QObject>
    #include <QNetworkReply>

    class NetworkReply : public QNetworkReply
    {
    Q_OBJECT

    public:
    NetworkReply(QNetworkReply* reply, QObject* parent);

    virtual void abort();
    virtual void close();
    virtual bool isSequential() const;
    
    virtual qint64 bytesAvailable() const;
    
    virtual qint64 readData(char* data, qint64 maxlen);
    
    QByteArray data();
    

    public slots:
    void ignoreSslErrors();
    void applyMetaData();
    void errorInternal(QNetworkReply::NetworkError _error);
    void handleReadyRead();
    void handleFinished();

    private:
    void readInternal();
    QNetworkReply* m_reply;
    QByteArray m_data;
    QByteArray m_buffer;

    };

    NetworkReply.cpp################################################################

    NetworkReply::NetworkReply(QNetworkReply* reply, QObject* parent)
    : QNetworkReply(parent)
    , m_reply(reply)
    {
    m_reply->setParent(this);

    setOperation(m_reply->operation());
    setRequest(m_reply->request());
    setUrl(m_reply->url());

    if (m_reply->isFinished()) {
    readInternal();
    setFinished(true);
    }

    applyMetaData();

    connect(m_reply, SIGNAL(metaDataChanged()), SLOT(applyMetaData()));
    connect(m_reply, SIGNAL(readyRead()), SLOT(handleReadyRead()));
    connect(m_reply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(errorInternal(QNetworkReply::NetworkError)));
    connect(m_reply, SIGNAL(finished()), SLOT(handleFinished()));

    connect(m_reply, SIGNAL(uploadProgress(qint64,qint64)), SIGNAL(uploadProgress(qint64,qint64)));
    connect(m_reply, SIGNAL(downloadProgress(qint64,qint64)), SIGNAL(downloadProgress(qint64,qint64)));
    connect(m_reply, SIGNAL(sslErrors(const QList<QSslError> &)), SIGNAL(sslErrors(const QList<QSslError> &)));

    setOpenMode(ReadOnly);

    }

    void NetworkReply::abort() {
    m_reply->abort();
    }
    void NetworkReply::close() {
    m_reply->close();
    }
    bool NetworkReply::isSequential() const {
    return m_reply->isSequential();
    }

    void NetworkReply::handleFinished() {
    setFinished(true);
    emit finished();
    }

    qint64 NetworkReply::bytesAvailable() const
    {
    return m_buffer.size() + QIODevice::bytesAvailable();
    }

    qint64 NetworkReply::readData(char* data, qint64 maxlen)
    {
    qint64 size = qMin(maxlen, qint64(m_buffer.size()));
    memcpy(data, m_buffer.constData(), size);
    m_buffer.remove(0, size);
    return size;
    }

    void NetworkReply::ignoreSslErrors() { m_reply->ignoreSslErrors(); }
    void NetworkReply::applyMetaData() {

    foreach(QNetworkReply::RawHeaderPair header, m_reply->rawHeaderPairs()){
    setRawHeader(header.first, header.second);

    }

    setAttribute(QNetworkRequest::HttpStatusCodeAttribute, m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute));
    setAttribute(QNetworkRequest::HttpReasonPhraseAttribute, m_reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute));
    setAttribute(QNetworkRequest::RedirectionTargetAttribute, m_reply->attribute(QNetworkRequest::RedirectionTargetAttribute));
    setAttribute(QNetworkRequest::ConnectionEncryptedAttribute, m_reply->attribute(QNetworkRequest::ConnectionEncryptedAttribute));
    setAttribute(QNetworkRequest::CacheLoadControlAttribute, m_reply->attribute(QNetworkRequest::CacheLoadControlAttribute));
    setAttribute(QNetworkRequest::CacheSaveControlAttribute, m_reply->attribute(QNetworkRequest::CacheSaveControlAttribute));
    setAttribute(QNetworkRequest::SourceIsFromCacheAttribute, m_reply->attribute(QNetworkRequest::SourceIsFromCacheAttribute));
    setAttribute(QNetworkRequest::DoNotBufferUploadDataAttribute, m_reply->attribute(QNetworkRequest::DoNotBufferUploadDataAttribute));
    emit metaDataChanged();
    }

    void NetworkReply::errorInternal(QNetworkReply::NetworkError _error)
    {
    setError(_error, errorString());
    emit error(_error);
    }

    void NetworkReply::readInternal() {
    QByteArray data = m_reply->readAll();
    m_data += data;
    m_buffer += data;
    }

    void NetworkReply::handleReadyRead()
    {
    readInternal();
    emit readyRead();
    }

    QByteArray NetworkReply::data() {
    return m_data;
    }


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.