1 #include "networkaccess.h"
10 const QString USER_AGENT = QString(Constants::APP_NAME)
11 + " " + Constants::VERSION
12 + " (" + Constants::WEBSITE + ")";
15 const QString USER_AGENT = "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.237 Safari/534.10";
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::AutoConnection);
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() {
33 QUrl redirection = networkReply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
34 if (redirection.isValid()) {
36 // qDebug() << "Redirect!"; // << redirection;
38 QNetworkReply *redirectReply = The::http()->simpleGet(redirection, networkReply->operation());
40 setParent(redirectReply);
41 networkReply->deleteLater();
42 networkReply = redirectReply;
44 // when the request is finished we'll invoke the target method
45 connect(networkReply, SIGNAL(finished()), this, SLOT(finished()), Qt::AutoConnection);
47 // monitor downloadProgress to impl timeout
48 connect(networkReply, SIGNAL(downloadProgress(qint64,qint64)),
49 SLOT(downloadProgress(qint64,qint64)), Qt::AutoConnection);
50 readTimeoutTimer->start();
53 connect(networkReply, SIGNAL(error(QNetworkReply::NetworkError)),
54 SLOT(requestError(QNetworkReply::NetworkError)));
60 emit finished(networkReply);
62 // get the HTTP response body
63 QByteArray bytes = networkReply->readAll();
68 // this will also delete this NetworkReply as the QNetworkReply is its parent
69 networkReply->deleteLater();
72 void NetworkReply::requestError(QNetworkReply::NetworkError /* code */) {
73 emit error(networkReply);
76 void NetworkReply::downloadProgress(qint64 bytesReceived, qint64 /* bytesTotal */) {
77 // qDebug() << "Downloading" << bytesReceived << bytesTotal;
78 if (bytesReceived > 0) {
79 readTimeoutTimer->stop();
80 disconnect(networkReply, SIGNAL(downloadProgress(qint64,qint64)),
81 this, SLOT(downloadProgress(qint64,qint64)));
85 void NetworkReply::readTimeout() {
86 // qDebug() << "HTTP read timeout" << networkReply->url();
87 networkReply->disconnect();
88 networkReply->abort();
90 QNetworkReply *retryReply = The::http()->simpleGet(networkReply->url(), networkReply->operation());
92 setParent(retryReply);
93 networkReply->deleteLater();
94 networkReply = retryReply;
96 // when the request is finished we'll invoke the target method
97 connect(networkReply, SIGNAL(finished()), this, SLOT(finished()), Qt::AutoConnection);
99 // monitor downloadProgress to impl timeout
100 connect(networkReply, SIGNAL(downloadProgress(qint64,qint64)),
101 SLOT(downloadProgress(qint64,qint64)), Qt::AutoConnection);
102 readTimeoutTimer->start();
105 connect(networkReply, SIGNAL(error(QNetworkReply::NetworkError)),
106 SLOT(requestError(QNetworkReply::NetworkError)));
108 // emit error(networkReply);
111 /* --- NetworkAccess --- */
113 NetworkAccess::NetworkAccess( QObject* parent) : QObject( parent ) {}
115 QNetworkReply* NetworkAccess::manualGet(QNetworkRequest request, int operation) {
117 QNetworkAccessManager *manager = The::networkAccessManager();
118 // manager->setCookieJar(new QNetworkCookieJar());
120 QNetworkReply *networkReply;
123 case QNetworkAccessManager::GetOperation:
124 qDebug() << "GET" << request.url().toEncoded();
125 networkReply = manager->get(request);
128 case QNetworkAccessManager::HeadOperation:
129 qDebug() << "HEAD" << request.url().toEncoded();
130 networkReply = manager->head(request);
134 qDebug() << "Unknown operation:" << operation;
140 connect(networkReply, SIGNAL(error(QNetworkReply::NetworkError)),
141 this, SLOT(error(QNetworkReply::NetworkError)));
146 QNetworkReply* NetworkAccess::simpleGet(QUrl url, int operation) {
148 QNetworkRequest request(url);
149 request.setRawHeader("User-Agent", USER_AGENT.toUtf8());
150 request.setRawHeader("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
151 request.setRawHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
152 request.setRawHeader("Accept-Language", "en-us,en;q=0.5");
153 request.setRawHeader("Connection", "Keep-Alive");
155 return manualGet(request, operation);
158 NetworkReply* NetworkAccess::get(const QUrl url) {
160 QNetworkReply *networkReply = simpleGet(url);
161 NetworkReply *reply = new NetworkReply(networkReply);
164 connect(networkReply, SIGNAL(error(QNetworkReply::NetworkError)),
165 reply, SLOT(requestError(QNetworkReply::NetworkError)));
167 // when the request is finished we'll invoke the target method
168 connect(networkReply, SIGNAL(finished()), reply, SLOT(finished()), Qt::AutoConnection);
174 NetworkReply* NetworkAccess::head(const QUrl url) {
176 QNetworkReply *networkReply = simpleGet(url, QNetworkAccessManager::HeadOperation);
177 NetworkReply *reply = new NetworkReply(networkReply);
180 connect(networkReply, SIGNAL(error(QNetworkReply::NetworkError)),
181 reply, SLOT(requestError(QNetworkReply::NetworkError)));
183 // when the request is finished we'll invoke the target method
184 connect(networkReply, SIGNAL(finished()), reply, SLOT(finished()), Qt::AutoConnection);
193 QNetworkReply* NetworkAccess::syncGet(QUrl url) {
197 networkReply = simpleGet(url);
198 connect(networkReply, SIGNAL(metaDataChanged()),
199 this, SLOT(syncMetaDataChanged()), Qt::AutoConnection);
200 connect(networkReply, SIGNAL(finished()),
201 this, SLOT(syncFinished()), Qt::AutoConnection);
202 connect(networkReply, SIGNAL(error(QNetworkReply::NetworkError)),
203 this, SLOT(error(QNetworkReply::NetworkError)));
205 // A little trick to make this function blocking
207 // Do something else, maybe even network processing events
208 qApp->processEvents();
211 networkReply->deleteLater();
216 void NetworkAccess::syncMetaDataChanged() {
218 QUrl redirection = networkReply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
219 if (redirection.isValid()) {
221 qDebug() << "Redirect" << redirection;
222 networkReply->deleteLater();
223 syncGet(redirection);
226 QNetworkAccessManager *manager = The::networkAccessManager();
227 networkReply->deleteLater();
228 networkReply = manager->get(QNetworkRequest(redirection));
229 connect(networkReply, SIGNAL(metaDataChanged()),
230 this, SLOT(metaDataChanged()), Qt::AutoConnection);
231 connect(networkReply, SIGNAL(finished()),
232 this, SLOT(finished()), Qt::AutoConnection);
238 void NetworkAccess::syncFinished() {
243 void NetworkAccess::error(QNetworkReply::NetworkError code) {
244 // get the QNetworkReply that sent the signal
245 QNetworkReply *networkReply = static_cast<QNetworkReply *>(sender());
247 qDebug() << "Cannot get sender";
252 if (networkReply->operation() == QNetworkAccessManager::HeadOperation)
255 // report the error in the status bar
256 QMainWindow* mainWindow = dynamic_cast<QMainWindow*>(qApp->topLevelWidgets().first());
257 if (mainWindow) mainWindow->statusBar()->showMessage(
258 tr("Network error: %1").arg(networkReply->errorString()));
260 qDebug() << "Network error:" << networkReply->errorString() << code;
262 networkReply->deleteLater();
265 QByteArray NetworkAccess::syncGetBytes(QUrl url) {
266 return syncGet(url)->readAll();
269 QString NetworkAccess::syncGetString(QUrl url) {
270 return QString::fromUtf8(syncGetBytes(url));