]> git.sur5r.net Git - minitube/blob - src/networkaccess.cpp
fallback to english categories
[minitube] / src / networkaccess.cpp
1 #include "networkaccess.h"
2 #include "constants.h"
3 #include <QtGui>
4
5 namespace The {
6 NetworkAccess* http();
7 }
8
9 /*
10 const QString USER_AGENT = QString(Constants::NAME)
11                            + " " + Constants::VERSION
12                            + " (" + Constants::WEBSITE + ")";
13 */
14
15 const QString USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11";
16
17 NetworkReply::NetworkReply(QNetworkReply *networkReply) : QObject(networkReply) {
18     this->networkReply = networkReply;
19     setupReply();
20
21     readTimeoutTimer = new QTimer(this);
22     readTimeoutTimer->setInterval(10000);
23     readTimeoutTimer->setSingleShot(true);
24     connect(readTimeoutTimer, SIGNAL(timeout()), SLOT(readTimeout()), Qt::UniqueConnection);
25     readTimeoutTimer->start();
26 }
27
28 void NetworkReply::setupReply() {
29     connect(networkReply, SIGNAL(error(QNetworkReply::NetworkError)),
30             SLOT(requestError(QNetworkReply::NetworkError)), Qt::UniqueConnection);
31     connect(networkReply, SIGNAL(finished()),
32             SLOT(finished()), Qt::UniqueConnection);
33     connect(networkReply, SIGNAL(downloadProgress(qint64,qint64)),
34             SLOT(downloadProgress(qint64,qint64)), Qt::UniqueConnection);
35 }
36
37 void NetworkReply::finished() {
38     QUrl redirection = networkReply->attribute(
39                 QNetworkRequest::RedirectionTargetAttribute).toUrl();
40     if (redirection.isValid()) {
41         if (networkReply->operation() == QNetworkAccessManager::GetOperation
42                 || networkReply->operation() == QNetworkAccessManager::HeadOperation) {
43             QNetworkReply *redirectReply =
44                     The::http()->request(redirection, networkReply->operation());
45             setParent(redirectReply);
46             networkReply->deleteLater();
47             networkReply = redirectReply;
48             setupReply();
49             readTimeoutTimer->start();
50             return;
51         } else qWarning("Redirection not supported");
52     }
53
54     if (receivers(SIGNAL(data(QByteArray))) > 0)
55         emit data(networkReply->readAll());
56     else if (receivers(SIGNAL(finished(QNetworkReply*))) > 0)
57         emit finished(networkReply);
58
59 #ifndef QT_NO_DEBUG_OUTPUT
60     if (!networkReply->attribute(QNetworkRequest::SourceIsFromCacheAttribute).toBool())
61         qDebug() << networkReply->url().toEncoded();
62 #endif
63
64     // bye bye my reply
65     // this will also delete this NetworkReply as the QNetworkReply is its parent
66     networkReply->deleteLater();
67 }
68
69 void NetworkReply::requestError(QNetworkReply::NetworkError code) {
70     qDebug() << networkReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt()
71              << networkReply->errorString() << code;
72     emit error(networkReply);
73 }
74
75 void NetworkReply::downloadProgress(qint64 bytesReceived, qint64 /* bytesTotal */) {
76     // qDebug() << "Downloading" << bytesReceived << bytesTotal << networkReply->url();
77     if (bytesReceived > 0 && readTimeoutTimer->isActive()) {
78         readTimeoutTimer->stop();
79         disconnect(networkReply, SIGNAL(downloadProgress(qint64,qint64)),
80                    this, SLOT(downloadProgress(qint64,qint64)));
81     }
82 }
83
84 void NetworkReply::readTimeout() {
85     networkReply->disconnect();
86     networkReply->abort();
87     networkReply->deleteLater();
88
89     if (networkReply->operation() != QNetworkAccessManager::GetOperation
90             || networkReply->operation() != QNetworkAccessManager::HeadOperation) {
91         emit error(networkReply);
92         return;
93     }
94
95     QNetworkReply *retryReply = The::http()->request(networkReply->url(), networkReply->operation());
96     setParent(retryReply);
97     networkReply = retryReply;
98     setupReply();
99 }
100
101 /* --- NetworkAccess --- */
102
103 NetworkAccess::NetworkAccess( QObject* parent) : QObject( parent ) {}
104
105 QNetworkRequest NetworkAccess::buildRequest(QUrl url) {
106     QNetworkRequest request(url);
107     request.setRawHeader("User-Agent", USER_AGENT.toUtf8());
108     request.setRawHeader("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
109     request.setRawHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
110     request.setRawHeader("Accept-Language", "en-us,en;q=0.5");
111     request.setRawHeader("Connection", "Keep-Alive");
112     return request;
113 }
114
115 QNetworkReply* NetworkAccess::request(QUrl url, int operation, const QByteArray& body) {
116     QNetworkAccessManager *manager = The::networkAccessManager();
117
118     QNetworkRequest request = buildRequest(url);
119
120     QNetworkReply *networkReply;
121     switch (operation) {
122
123     case QNetworkAccessManager::GetOperation:
124         networkReply = manager->get(request);
125         break;
126
127     case QNetworkAccessManager::HeadOperation:
128         networkReply = manager->head(request);
129         break;
130
131     case QNetworkAccessManager::PostOperation:
132         if (!body.isEmpty())
133             request.setRawHeader("Content-Type", "application/x-www-form-urlencoded");
134         networkReply = manager->post(request, body);
135         break;
136
137     default:
138         qWarning() << "Unknown operation:" << operation;
139         return 0;
140     }
141
142     return networkReply;
143 }
144
145 NetworkReply* NetworkAccess::get(const QUrl url) {
146     QNetworkReply *networkReply = request(url);
147     return new NetworkReply(networkReply);
148 }
149
150 NetworkReply* NetworkAccess::head(const QUrl url) {
151     QNetworkReply *networkReply = request(url, QNetworkAccessManager::HeadOperation);
152     return new NetworkReply(networkReply);
153 }
154
155 NetworkReply* NetworkAccess::post(const QUrl url, const QMap<QString, QString>& params) {
156     QByteArray body;
157     QMapIterator<QString, QString> i(params);
158     while (i.hasNext()) {
159         i.next();
160         body += QUrl::toPercentEncoding(i.key())
161                 + '='
162                 + QUrl::toPercentEncoding(i.value())
163                 + '&';
164     }
165     QNetworkReply *networkReply = request(url, QNetworkAccessManager::PostOperation, body);
166     return new NetworkReply(networkReply);
167 }