Qt: QNetworkAccessManager stoppt download



  • Guten Abend,

    ich habe ein Problem mit dem QNetworkAccessManager (glaube ich zumindest). Er lädt größere HTML Seiten nur "halb". Um genau zu sein, er lädt max 32302 Zeichen. Ich muss ehrlich sein, ich habe keine Ahnung woran das liegt.

    #ifndef DOWNLOADMANAGER
    #define DOWNLOADMANAGER
    
    #include <QCoreApplication>
    #include <QFile>
    #include <QFileInfo>
    #include <QList>
    #include <QNetworkAccessManager>
    #include <QNetworkRequest>
    #include <QString>
    #include <map>
    #include <QNetworkReply>
    #include <QStringList>
    #include <QTimer>
    #include <QMap>
    #include "datentypen.h"
    #include <QUrl>
    #include <fstream>
    #include <stdio.h>
    
    class DownloadManager: public QObject
    {
        Q_OBJECT
    public:
        void ClearSource();
        QString getCurrentHost();
        QByteArray gzipDecompress( QByteArray compressData );
        QStringList getSource();
        DownloadManager();
        ~DownloadManager();
        void doDownload(const QUrl &url, bool loeschen = false, const QByteArray Daten = "");
        void doDownload(const QString &url, bool loeschen = false, const QByteArray Daten = "");
        void LoadSourceFromData(const char* filename);
       // QString saveFileName(const QUrl &url);
        bool isFinished();
        QStringList getSRC();
        QStringList getHREF();
        QString getCookie(QUrl, QString was);
        QString getCookie(QUrl);
    public slots:
        void downloadFinished(QNetworkReply *reply);
    signals:
        void finished();
        void Ausgabe(QString);
    private:
        void setCookie(QString Host, QString t);
        QString getNext(QString &t);
        QString getValue(QString &t, QString was);
        std::ofstream ausg;
        QNetworkAccessManager manager;
        QList<QNetworkReply *> currentDownloads;
        QMap<QNetworkReply*, bool> Loeschen;
        QMap<QString, QString> Cookie;
        bool finish;
        QStringList *Source;
        QString CurrentHost;
    };
    
    #endif
    
    #include "downloadmanager.h"
    #include <fstream>
    #include <zlib.h>
    #include <QDebug>
    #include <fstream>
    #include <QMessageBox>
    
    DownloadManager::DownloadManager()
    {
        Source = new QStringList();
        ausg.open("/home/fettpet/header.txt");
        connect(&manager, SIGNAL(finished(QNetworkReply*)),
                SLOT(downloadFinished(QNetworkReply*)));
        finish = true;
    }
    
    QString DownloadManager::getCurrentHost(){
        return CurrentHost;
    }
    
    QString DownloadManager::getCookie(QUrl url, QString was){
        if(Cookie.keys().contains(url.host())){
            QString buffer = Cookie.take(url.host());
            if(buffer.contains(was)){
                buffer = buffer.mid(buffer.indexOf(was));
                buffer = buffer.mid(buffer.indexOf("=")+1);
                return buffer.left(buffer.indexOf(";"));
            } else{
                return "";
            }
        }else {
            return "";
        }
    }
    QString DownloadManager::getCookie(QUrl url){
        if(Cookie.keys().contains(url.host())){
            return Cookie.take(url.host());
        }else {
            return "";
        }
    }
    void DownloadManager::setCookie(QString Host, QString t){
        if(!Cookie.keys().contains(Host)){
            Cookie.insert(Host,t);
            return;
        }
        QString CurrentCookie = Cookie.take(Host);
        while(!t.isEmpty()){
            QString buffer = getNext(t);
            QString key= buffer.left(buffer.indexOf("="));
            QString value = buffer.mid(buffer.indexOf("=")+1);
            if(CurrentCookie.contains(key)){
                buffer = CurrentCookie.left(CurrentCookie.indexOf(key)) ;
                buffer += key + "=" + value + " ;";
                CurrentCookie = CurrentCookie.mid(CurrentCookie.indexOf(key));
                CurrentCookie = CurrentCookie.mid(CurrentCookie.indexOf(";")+1);
                CurrentCookie = buffer + CurrentCookie;
            } else {
                CurrentCookie += key + "=" + value + " ;";
            }
    
        };
        Cookie.insert(Host, CurrentCookie);
    }
    
    QString DownloadManager::getNext(QString &t){
        QString buffer;
        buffer = t.left(t.indexOf(";"));
        t = t.mid(t.indexOf(";")+2);
        return buffer;
    }
    QString DownloadManager::getValue(QString &t, QString was){
        if(t.contains(was)){
            QString buffer;
            buffer = t.mid(t.indexOf(was));
            buffer = buffer.mid(buffer.indexOf("=")+1);
            buffer = buffer.left(buffer.indexOf(";"));
            return buffer;
        }
        return "";
    }
    
    void DownloadManager::doDownload(const QUrl &url, bool loeschen, const QByteArray Daten)
    {
    
        CurrentHost = url.host();
        finish = false;
        QString buffer, bufferausg;
        bufferausg = buffer = url.toString();
        if(!buffer.contains("http")){
            buffer = "http://" + buffer;
        }
    
        buffer = buffer.replace("%3F","?");
        buffer = buffer.replace("%3D","=");
        buffer = buffer.replace("%26","&");
        buffer = buffer.replace("&amp;","&");
        const QUrl back(buffer);
        QNetworkRequest request(back);
        request.setRawHeader("User-Agent", "Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:14.0) Gecko/20100101 Firefox/14.0.1");
        request.setRawHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
        request.setRawHeader("Accept-Language" ,"de-DE,de;q=0.8,en-US;q=0.5,en;q=0.3");
        request.setRawHeader("Accept-Encoding", "gzip, deflate");
        if(Cookie.keys().contains(CurrentHost)){
            ausg << "Cookie: " << Cookie.take(CurrentHost).toStdString() << std::endl;
            request.setRawHeader("Cookie", Cookie.take(CurrentHost).toStdString().c_str());
        }
        request.setRawHeader("DNT", "1");
        request.setRawHeader("Connection", "keep-alive");
    
        QNetworkReply *reply;
        if( Daten.size() == 0){
            reply = manager.get(request);
        }else {
           reply = manager.post(request, Daten);
         }
         currentDownloads.append(reply);
         Loeschen.insert(reply, loeschen);
    }
    
    void DownloadManager::doDownload(const QString &url, bool loeschen, const QByteArray Daten){
        doDownload(QUrl(url), loeschen, Daten);
    }
    
    QStringList DownloadManager::getSRC(){
        QString buffer, bufferjava;
        QStringList href;
        for(int i=0; i<Source->size(); ++i){
            buffer += Source->value(i);
        }
    
        while(buffer.contains("script type=\"text/javascript\"")){
            bufferjava = buffer.left(buffer.indexOf("<script type=\"text/javascript\""));
            bufferjava += buffer.mid(buffer.indexOf("</script>")+5);
            buffer = bufferjava;
        }
    
        while(buffer.contains("src=")){
    
            buffer = buffer.mid(buffer.indexOf("src=")+5);
            QString tohref = buffer.left(buffer.indexOf("\""));
            tohref = tohref.replace("&amp;", "&");
            if(tohref.contains("://")){
                href.append(tohref);
            }else {
    
                if(tohref[0] == QChar('/')){
                    tohref = "http://" + getCurrentHost() +tohref;
                } else {
                    tohref = "http://" + getCurrentHost() +"/"+tohref;
                }
                href.append(tohref);
            }
        }
        return href;
    }
    
    QStringList DownloadManager::getHREF(){
        QString buffer;
        QStringList src;
        for(int i=0; i<Source->size(); ++i){
            buffer += Source->value(i);
        }
        while(buffer.contains("href=")){
            buffer = buffer.mid(buffer.indexOf("href=")+6);
            QString tohref = buffer.left(buffer.indexOf("\""));
            tohref = tohref.replace("&amp;", "&");
            if(tohref.contains("://")){
                src.append(tohref);
            } else {
                if(tohref[0] == QChar('/')){
                    tohref = "http://" + getCurrentHost() +tohref;
                } else {
                    tohref = "http://" + getCurrentHost() +"/"+tohref;
                }
                src.append(tohref);
            }
        }
        return src;
    }
    
    QStringList DownloadManager::getSource(){
        return *Source;
    }
    bool DownloadManager::isFinished(){
        return finish;
    }
    DownloadManager::~DownloadManager(){
        ausg.close();
    }
    void DownloadManager::ClearSource(){
        Source->clear();
    }
    
    void DownloadManager::downloadFinished(QNetworkReply *reply){
        std::ofstream datei;
        datei.open("/home/fettpet/Finished.txt", std::ios::app);
    
        QUrl url = reply->url();
        datei << url.toString().toStdString() << " size: ";
    
        if(reply->rawHeader("Location") != ""){
            QString buffer;
            buffer = reply->rawHeader("Location");
            datei << buffer.toStdString() << std::endl;
    
            emit Ausgabe(buffer);
            doDownload(QUrl(buffer));
            currentDownloads.removeAll(reply);
            reply->deleteLater();
            return;
        }
        if(reply->rawHeader("Set-Cookie") != ""){
            QString buffer;
            buffer = reply->rawHeader("Set-Cookie");
            ausg << "Set-Cookie: " << QString(reply->rawHeader("Set-Cookie")).toStdString() << std::endl;
            ausg << "Host" << reply->url().toString().toStdString() << std::endl;
            setCookie(reply->url().host(), buffer);
        }
        QString Kompriemirungsalgo = reply->rawHeader("Content-Encoding");
        if (reply->error()) {
            fprintf(stderr, "Download of %s failed: %s\n",
                    url.toEncoded().constData(),
                    qPrintable(reply->errorString()));
        } else {
            if(Loeschen.take(reply)) Source->clear();
            if(Kompriemirungsalgo != "gzip"){
                Source->append(reply->readAll());
            } else if (Kompriemirungsalgo == "gzip"){
                Source->append(gzipDecompress(reply->readAll()));
            }
        }
        currentDownloads.removeAll(reply);
        reply->deleteLater();
        if (currentDownloads.isEmpty()){
             finish = true;
             emit finished();
        }
        datei << Source->value(0).size() << std::endl;
    }
    
    // Komprimierung
    QByteArray DownloadManager::gzipDecompress( QByteArray compressData )
    {
       //strip header
       compressData.remove(0, 10);
    
       const int buffer_size = 32768;
       quint8 buffer[buffer_size];
    
       z_stream cmpr_stream;
       cmpr_stream.next_in = (unsigned char *)compressData.data();
       cmpr_stream.avail_in = compressData.size();
       cmpr_stream.total_in = 0;
    
       cmpr_stream.next_out = buffer;
       cmpr_stream.avail_out = buffer_size;
       cmpr_stream.total_out = 0;
    
       cmpr_stream.zalloc = Z_NULL;
       cmpr_stream.zfree = Z_NULL;
       cmpr_stream.opaque = Z_NULL;
    
       int status = inflateInit2( &cmpr_stream, -8 );
       if (status != Z_OK) {
           qDebug() << "cmpr_stream error!";
       }
    
       QByteArray uncompressed;
       do {
           cmpr_stream.next_out = buffer;
           cmpr_stream.avail_out = buffer_size;
    
           status = inflate( &cmpr_stream, Z_NO_FLUSH );
    
           if (status == Z_OK || status == Z_STREAM_END)
           {
               QByteArray chunk = QByteArray::fromRawData((char *)buffer, buffer_size - cmpr_stream.avail_out);
               uncompressed.append( chunk );
           }
           else
           {
               inflateEnd(&cmpr_stream);
               break;
           }
    
           if (status == Z_STREAM_END)
           {
               inflateEnd(&cmpr_stream);
               break;
           }
       }
       while (cmpr_stream.avail_out == 0);
    
       return uncompressed;
    }
    
    /******************************************************************************************
                                    Debugging
    *******************************************************************************************/
    
    void DownloadManager::LoadSourceFromData(const char* filename) {
        std::fstream datei;
        datei.open(filename, std::ios::in);
        std::string buffer;
        while(!datei.eof()){
            datei >> buffer;
            Source->append(buffer.c_str());
        }
    }
    

    Weiß einer Rat?



  • hab den Fehler gefunden. In der Dekomprimierung hatte ich die Zeile stehen.
    const int buffer_size = 32768;
    den Algorithmus hatte ich hier geklaut
    http://stackoverflow.com/questions/5741657/error-decompressing-gzip-data-using-qt
    Wenn ich das richtig verstehe darf ich die buffer_size auch nicht ändern (z.B. einfach verdoppeln) oder?


Anmelden zum Antworten