From b7f313a35c0c6ba15becbf4fe40de63dee0ecbea Mon Sep 17 00:00:00 2001 From: Dmitry Maslennikov Date: Sun, 10 Mar 2013 20:25:09 +0200 Subject: [PATCH] add cookies for redirect, cookies for auto download torrent from rss, add support gzip --- src/downloadthread.cpp | 63 +++++++++++++++++++++++++++++++-- src/downloadthread.h | 2 ++ src/qtlibtorrent/qbtsession.cpp | 4 +-- src/qtlibtorrent/qbtsession.h | 2 +- src/rss/rssfeed.cpp | 2 +- 5 files changed, 66 insertions(+), 7 deletions(-) diff --git a/src/downloadthread.cpp b/src/downloadthread.cpp index 6a765f85a..7c0e665da 100644 --- a/src/downloadthread.cpp +++ b/src/downloadthread.cpp @@ -50,6 +50,56 @@ DownloadThread::DownloadThread(QObject* parent) : QObject(parent) { #endif } +QByteArray DownloadThread::gUncompress(Bytef *inData, size_t len) { + if (len <= 4) { + qWarning("gUncompress: Input data is truncated"); + return QByteArray(); + } + + QByteArray result; + z_stream strm; + static const int CHUNK_SIZE = 1024; + char out[CHUNK_SIZE]; + + /* allocate inflate state */ + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.avail_in = len; + strm.next_in = inData; + + const int windowBits = 15; + const int ENABLE_ZLIB_GZIP = 32; + + int ret = inflateInit2(&strm, windowBits|ENABLE_ZLIB_GZIP); // gzip decoding + if (ret != Z_OK) + return QByteArray(); + + // run inflate() + do { + strm.avail_out = CHUNK_SIZE; + strm.next_out = reinterpret_cast(out); + + ret = inflate(&strm, Z_NO_FLUSH); + Q_ASSERT(ret != Z_STREAM_ERROR); // state not clobbered + + switch (ret) { + case Z_NEED_DICT: + case Z_DATA_ERROR: + case Z_MEM_ERROR: + (void) inflateEnd(&strm); + + return QByteArray(); + } + + result.append(out, CHUNK_SIZE - strm.avail_out); + } while (!strm.avail_out); + + // clean up and return + inflateEnd(&strm); + return result; +} + void DownloadThread::processDlFinished(QNetworkReply* reply) { QString url = reply->url().toString(); qDebug("Download finished: %s", qPrintable(url)); @@ -72,7 +122,8 @@ void DownloadThread::processDlFinished(QNetworkReply* reply) { const QString newUrlString = newUrl.toString(); qDebug("Redirecting from %s to %s", qPrintable(url), qPrintable(newUrlString)); m_redirectMapping.insert(newUrlString, url); - downloadUrl(newUrlString); + // redirecting with first cookies + downloadUrl(newUrlString, m_networkManager.cookieJar()->cookiesForUrl(url)); reply->deleteLater(); return; } @@ -87,8 +138,12 @@ void DownloadThread::processDlFinished(QNetworkReply* reply) { QString filePath = tmpfile->fileName(); qDebug("Temporary filename is: %s", qPrintable(filePath)); if (reply->isOpen() || reply->open(QIODevice::ReadOnly)) { - // TODO: Support GZIP compression - tmpfile->write(reply->readAll()); + QByteArray replyData = reply->readAll(); + if (reply->rawHeader("Content-Encoding") == "gzip") { + // uncompress gzip reply + replyData = gUncompress(reinterpret_cast(replyData.data()), replyData.length()); + } + tmpfile->write(replyData); tmpfile->close(); // XXX: tmpfile needs to be deleted on Windows before using the file // or it will complain that the file is used by another process. @@ -136,6 +191,8 @@ QNetworkReply* DownloadThread::downloadUrl(const QString &url, const QListcookiesForUrl(url).at(i).name().data(), m_networkManager.cookieJar()->cookiesForUrl(url).at(i).value().data()); qDebug("Domain: %s, Path: %s", qPrintable(m_networkManager.cookieJar()->cookiesForUrl(url).at(i).domain()), qPrintable(m_networkManager.cookieJar()->cookiesForUrl(url).at(i).path())); } + // accept gzip + request.setRawHeader("Accept-Encoding", "gzip"); return m_networkManager.get(request); } diff --git a/src/downloadthread.h b/src/downloadthread.h index 6bdc6a7a3..be4360306 100644 --- a/src/downloadthread.h +++ b/src/downloadthread.h @@ -36,6 +36,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE class QNetworkAccessManager; @@ -62,6 +63,7 @@ private slots: #endif private: + static QByteArray gUncompress(Bytef *inData, size_t len); QString errorCodeToString(QNetworkReply::NetworkError status); void applyProxySettings(); diff --git a/src/qtlibtorrent/qbtsession.cpp b/src/qtlibtorrent/qbtsession.cpp index b629fc67f..64b16e92c 100644 --- a/src/qtlibtorrent/qbtsession.cpp +++ b/src/qtlibtorrent/qbtsession.cpp @@ -2673,14 +2673,14 @@ void QBtSession::addMagnetSkipAddDlg(const QString& uri, const QString& save_pat addMagnetUri(uri, false); } -void QBtSession::downloadUrlAndSkipDialog(QString url, QString save_path, QString label) { +void QBtSession::downloadUrlAndSkipDialog(QString url, QString save_path, QString label, const QList& cookies) { //emit aboutToDownloadFromUrl(url); const QUrl qurl = QUrl::fromEncoded(url.toUtf8()); if (!save_path.isEmpty() || !label.isEmpty()) savepathLabel_fromurl[qurl] = qMakePair(save_path, label); url_skippingDlg << qurl; // Launch downloader thread - downloader->downloadTorrentUrl(url); + downloader->downloadTorrentUrl(url, cookies); } // Add to Bittorrent session the downloaded torrent file diff --git a/src/qtlibtorrent/qbtsession.h b/src/qtlibtorrent/qbtsession.h index 10fa54b71..0ed2207fb 100644 --- a/src/qtlibtorrent/qbtsession.h +++ b/src/qtlibtorrent/qbtsession.h @@ -126,7 +126,7 @@ public slots: void disableIPFilter(); void setQueueingEnabled(bool enable); void handleDownloadFailure(QString url, QString reason); - void downloadUrlAndSkipDialog(QString url, QString save_path=QString(), QString label=QString()); + void downloadUrlAndSkipDialog(QString url, QString save_path=QString(), QString label=QString(), const QList& cookies = QList()); // Session configuration - Setters void setListeningPort(int port); void setMaxConnections(int maxConnec); diff --git a/src/rss/rssfeed.cpp b/src/rss/rssfeed.cpp index def19c29b..b6a78af86 100644 --- a/src/rss/rssfeed.cpp +++ b/src/rss/rssfeed.cpp @@ -332,7 +332,7 @@ void RssFeed::downloadMatchingArticleTorrents() { if (torrent_url.startsWith("magnet:", Qt::CaseInsensitive)) QBtSession::instance()->addMagnetSkipAddDlg(torrent_url, matching_rule->savePath(), matching_rule->label()); else - QBtSession::instance()->downloadUrlAndSkipDialog(torrent_url, matching_rule->savePath(), matching_rule->label()); + QBtSession::instance()->downloadUrlAndSkipDialog(torrent_url, matching_rule->savePath(), matching_rule->label(), feedCookies()); } } }