1 #include "networkaccess.h"
10 const QString USER_AGENT = QString(Constants::NAME)
11 + " " + Constants::VERSION
12 + " (" + Constants::WEBSITE + ")";
15 const QString USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.46 Safari/536.5";
17 NetworkReply::NetworkReply(QNetworkReply *networkReply) : QObject(networkReply) {
18 this->networkReply = networkReply;
20 // monitor downloadProgress to impl timeout
21 connect(networkReply, SIGNAL(downloadProgress(qint64,qint64)),
22 SLOT(downloadProgress(qint64,qint64)), Qt::UniqueConnection);
24 readTimeoutTimer = new QTimer(this);
25 readTimeoutTimer->setInterval(5000);
26 readTimeoutTimer->setSingleShot(true);
27 connect(readTimeoutTimer, SIGNAL(timeout()), SLOT(readTimeout()));
28 readTimeoutTimer->start();
31 void NetworkReply::finished() {
32 // qDebug() << "Finished" << networkReply->url();
34 QUrl redirection = networkReply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
35 if (redirection.isValid()) {
37 // qDebug() << "Redirect!"; // << redirection;
39 QNetworkReply *redirectReply = The::http()->simpleGet(redirection, networkReply->operation());
41 setParent(redirectReply);
42 networkReply->deleteLater();
43 networkReply = redirectReply;
45 // when the request is finished we'll invoke the target method
46 connect(networkReply, SIGNAL(finished()), this, SLOT(finished()), Qt::UniqueConnection);
48 // monitor downloadProgress to impl timeout
49 connect(networkReply, SIGNAL(downloadProgress(qint64,qint64)),
50 SLOT(downloadProgress(qint64,qint64)), Qt::UniqueConnection);
51 readTimeoutTimer->start();
54 connect(networkReply, SIGNAL(error(QNetworkReply::NetworkError)),
55 SLOT(requestError(QNetworkReply::NetworkError)), Qt::UniqueConnection);
57 connect(readTimeoutTimer, SIGNAL(timeout()), SLOT(readTimeout()), Qt::UniqueConnection);
58 readTimeoutTimer->start();
63 emit data(networkReply->readAll());
64 emit finished(networkReply);
66 #ifndef QT_NO_DEBUG_OUTPUT
67 if (!networkReply->attribute(QNetworkRequest::SourceIsFromCacheAttribute).toBool()) {
68 qDebug() << networkReply->url().toEncoded();
73 // this will also delete this NetworkReply as the QNetworkReply is its parent
74 networkReply->deleteLater();
77 void NetworkReply::requestError(QNetworkReply::NetworkError /* code */) {
78 emit error(networkReply);
81 void NetworkReply::downloadProgress(qint64 bytesReceived, qint64 bytesTotal) {
82 // qDebug() << "Downloading" << bytesReceived << bytesTotal << networkReply->url();
83 if (bytesReceived > 0) {
84 readTimeoutTimer->stop();
85 disconnect(networkReply, SIGNAL(downloadProgress(qint64,qint64)),
86 this, SLOT(downloadProgress(qint64,qint64)));
90 void NetworkReply::readTimeout() {
91 // qDebug() << "HTTP read timeout" << networkReply->url();
92 networkReply->disconnect();
93 networkReply->abort();
95 QNetworkReply *retryReply = The::http()->simpleGet(networkReply->url(), networkReply->operation());
97 setParent(retryReply);
98 networkReply->deleteLater();
99 networkReply = retryReply;
101 // when the request is finished we'll invoke the target method
102 connect(networkReply, SIGNAL(finished()), this, SLOT(finished()), Qt::UniqueConnection);
104 // monitor downloadProgress to impl timeout
105 connect(networkReply, SIGNAL(downloadProgress(qint64,qint64)),
106 SLOT(downloadProgress(qint64,qint64)), Qt::UniqueConnection);
107 readTimeoutTimer->start();
110 connect(networkReply, SIGNAL(error(QNetworkReply::NetworkError)),
111 SLOT(requestError(QNetworkReply::NetworkError)));
113 // emit error(networkReply);
116 /* --- NetworkAccess --- */
118 NetworkAccess::NetworkAccess( QObject* parent) : QObject( parent ) {}
120 QNetworkReply* NetworkAccess::manualGet(QNetworkRequest request, int operation) {
122 QNetworkAccessManager *manager = The::networkAccessManager();
123 // manager->setCookieJar(new QNetworkCookieJar());
125 QNetworkReply *networkReply;
128 case QNetworkAccessManager::GetOperation:
129 // qDebug() << "GET" << request.url().toEncoded();
130 networkReply = manager->get(request);
133 case QNetworkAccessManager::HeadOperation:
134 // qDebug() << "HEAD" << request.url().toEncoded();
135 networkReply = manager->head(request);
139 qDebug() << "Unknown operation:" << operation;
145 connect(networkReply, SIGNAL(error(QNetworkReply::NetworkError)),
146 this, SLOT(error(QNetworkReply::NetworkError)));
151 QNetworkRequest NetworkAccess::buildRequest(QUrl url) {
152 QNetworkRequest request(url);
153 request.setRawHeader("User-Agent", USER_AGENT.toUtf8());
154 request.setRawHeader("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
155 request.setRawHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
156 request.setRawHeader("Accept-Language", "en-us,en;q=0.5");
157 request.setRawHeader("Connection", "Keep-Alive");
161 QNetworkReply* NetworkAccess::simpleGet(QUrl url, int operation) {
162 return manualGet(buildRequest(url), operation);
165 NetworkReply* NetworkAccess::get(const QUrl url) {
167 QNetworkReply *networkReply = simpleGet(url);
168 NetworkReply *reply = new NetworkReply(networkReply);
171 connect(networkReply, SIGNAL(error(QNetworkReply::NetworkError)),
172 reply, SLOT(requestError(QNetworkReply::NetworkError)));
174 // when the request is finished we'll invoke the target method
175 connect(networkReply, SIGNAL(finished()), reply, SLOT(finished()), Qt::UniqueConnection);
181 NetworkReply* NetworkAccess::head(const QUrl url) {
183 QNetworkReply *networkReply = simpleGet(url, QNetworkAccessManager::HeadOperation);
184 NetworkReply *reply = new NetworkReply(networkReply);
187 connect(networkReply, SIGNAL(error(QNetworkReply::NetworkError)),
188 reply, SLOT(requestError(QNetworkReply::NetworkError)));
190 // when the request is finished we'll invoke the target method
191 connect(networkReply, SIGNAL(finished()), reply, SLOT(finished()), Qt::UniqueConnection);
197 void NetworkAccess::error(QNetworkReply::NetworkError code) {
198 // get the QNetworkReply that sent the signal
199 QNetworkReply *networkReply = static_cast<QNetworkReply *>(sender());
201 qDebug() << "Cannot get sender";
205 networkReply->deleteLater();
208 if (networkReply->operation() == QNetworkAccessManager::HeadOperation)
211 // report the error in the status bar
212 QMainWindow* mainWindow = dynamic_cast<QMainWindow*>(qApp->topLevelWidgets().first());
213 if (mainWindow) mainWindow->statusBar()->showMessage(
214 tr("Network error: %1").arg(networkReply->errorString()));
216 qDebug() << "Network error:" << networkReply->errorString() << code;