choke uploadProgress signals
[profile/ivi/qtbase.git] / src / network / access / qnetworkreplyhttpimpl_p.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtNetwork module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #ifndef QNETWORKREPLYHTTPIMPL_P_H
43 #define QNETWORKREPLYHTTPIMPL_P_H
44
45 //
46 //  W A R N I N G
47 //  -------------
48 //
49 // This file is not part of the Qt API.  It exists for the convenience
50 // of the Network Access API.  This header file may change from
51 // version to version without notice, or even be removed.
52 //
53 // We mean it.
54 //
55
56 #include "qnetworkrequest.h"
57 #include "qnetworkreply.h"
58
59 #include "QtCore/qpointer.h"
60 #include "QtCore/qdatetime.h"
61 #include "QtCore/qsharedpointer.h"
62 #include "qatomic.h"
63
64 #include <QtNetwork/QNetworkCacheMetaData>
65 #include <private/qhttpnetworkrequest_p.h>
66 #include <private/qbytedata_p.h>
67 #include <private/qnetworkreply_p.h>
68 #include <QtNetwork/QNetworkProxy>
69 #include <QtNetwork/QNetworkSession>
70
71 #ifndef QT_NO_SSL
72 #include <QtNetwork/QSslConfiguration>
73 #endif
74
75 #ifndef QT_NO_HTTP
76
77 QT_BEGIN_NAMESPACE
78
79 class QIODevice;
80
81 class QNetworkReplyHttpImplPrivate;
82 class QNetworkReplyHttpImpl: public QNetworkReply
83 {
84     Q_OBJECT
85 public:
86     QNetworkReplyHttpImpl(QNetworkAccessManager* const, const QNetworkRequest&, QNetworkAccessManager::Operation&, QIODevice* outgoingData);
87     virtual ~QNetworkReplyHttpImpl();
88
89     void close();
90     void abort();
91     qint64 bytesAvailable() const;
92     bool isSequential () const;
93     qint64 size() const;
94     qint64 readData(char*, qint64);
95     void setReadBufferSize(qint64 size);
96     bool canReadLine () const;
97
98     Q_DECLARE_PRIVATE(QNetworkReplyHttpImpl)
99     Q_PRIVATE_SLOT(d_func(), void _q_startOperation())
100     Q_PRIVATE_SLOT(d_func(), void _q_cacheLoadReadyRead())
101     Q_PRIVATE_SLOT(d_func(), void _q_bufferOutgoingData())
102     Q_PRIVATE_SLOT(d_func(), void _q_bufferOutgoingDataFinished())
103 #ifndef QT_NO_BEARERMANAGEMENT
104     Q_PRIVATE_SLOT(d_func(), void _q_networkSessionConnected())
105     Q_PRIVATE_SLOT(d_func(), void _q_networkSessionFailed())
106     Q_PRIVATE_SLOT(d_func(), void _q_networkSessionUsagePoliciesChanged(QNetworkSession::UsagePolicies))
107 #endif
108     Q_PRIVATE_SLOT(d_func(), void _q_finished())
109     Q_PRIVATE_SLOT(d_func(), void _q_error(QNetworkReply::NetworkError, const QString &))
110
111     // From reply
112     Q_PRIVATE_SLOT(d_func(), void replyDownloadData(QByteArray))
113     Q_PRIVATE_SLOT(d_func(), void replyFinished())
114     Q_PRIVATE_SLOT(d_func(), void replyDownloadMetaData(QList<QPair<QByteArray,QByteArray> >,int,QString,bool,QSharedPointer<char>,qint64))
115     Q_PRIVATE_SLOT(d_func(), void replyDownloadProgressSlot(qint64,qint64))
116     Q_PRIVATE_SLOT(d_func(), void httpAuthenticationRequired(const QHttpNetworkRequest &, QAuthenticator *))
117     Q_PRIVATE_SLOT(d_func(), void httpError(QNetworkReply::NetworkError, const QString &))
118 #ifndef QT_NO_SSL
119     Q_PRIVATE_SLOT(d_func(), void replySslErrors(const QList<QSslError> &, bool *, QList<QSslError> *))
120     Q_PRIVATE_SLOT(d_func(), void replySslConfigurationChanged(const QSslConfiguration&))
121 #endif
122     Q_PRIVATE_SLOT(d_func(), void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *auth))
123
124     Q_PRIVATE_SLOT(d_func(), void resetUploadDataSlot(bool *r))
125     Q_PRIVATE_SLOT(d_func(), void wantUploadDataSlot(qint64))
126     Q_PRIVATE_SLOT(d_func(), void sentUploadDataSlot(qint64))
127     Q_PRIVATE_SLOT(d_func(), void emitReplyUploadProgress(qint64, qint64))
128
129
130 #ifndef QT_NO_SSL
131 protected:
132     void ignoreSslErrors();
133     void ignoreSslErrorsImplementation(const QList<QSslError> &errors);
134     void setSslConfigurationImplementation(const QSslConfiguration &configuration);
135     void sslConfigurationImplementation(QSslConfiguration &configuration) const;
136 #endif
137
138 signals:
139     // To HTTP thread:
140     void startHttpRequest();
141     void abortHttpRequest();
142     void readBufferSizeChanged(qint64 size);
143     void readBufferFreed(qint64 size);
144
145     void startHttpRequestSynchronously();
146
147     void haveUploadData(QByteArray dataArray, bool dataAtEnd, qint64 dataSize);
148 };
149
150 class QNetworkReplyHttpImplPrivate: public QNetworkReplyPrivate
151 {
152 public:
153
154     static QHttpNetworkRequest::Priority convert(const QNetworkRequest::Priority& prio);
155
156     enum State {
157         Idle,               // The reply is idle.
158         Buffering,          // The reply is buffering outgoing data.
159         Working,            // The reply is uploading/downloading data.
160         Finished,           // The reply has finished.
161         Aborted,            // The reply has been aborted.
162         WaitingForSession,  // The reply is waiting for the session to open before connecting.
163         Reconnecting        // The reply will reconnect to once roaming has completed.
164     };
165
166     QNetworkReplyHttpImplPrivate();
167     ~QNetworkReplyHttpImplPrivate();
168
169     bool start();
170     void _q_startOperation();
171
172     void _q_cacheLoadReadyRead();
173
174     void _q_bufferOutgoingData();
175     void _q_bufferOutgoingDataFinished();
176
177 #ifndef QT_NO_BEARERMANAGEMENT
178     void _q_networkSessionConnected();
179     void _q_networkSessionFailed();
180     void _q_networkSessionUsagePoliciesChanged(QNetworkSession::UsagePolicies);
181 #endif
182     void _q_finished();
183
184     void finished();
185     void error(QNetworkReply::NetworkError code, const QString &errorString);
186     void _q_error(QNetworkReply::NetworkError code, const QString &errorString);
187     void metaDataChanged();
188
189     void checkForRedirect(const int statusCode);
190
191     // incoming from user
192     QNetworkAccessManager *manager;
193     QNetworkAccessManagerPrivate *managerPrivate;
194     QHttpNetworkRequest httpRequest; // There is also a copy in the HTTP thread
195     bool synchronous;
196
197     State state;
198
199     // from http thread
200     int statusCode;
201     QString reasonPhrase;
202
203     // upload
204     QNonContiguousByteDevice* createUploadByteDevice();
205     QSharedPointer<QNonContiguousByteDevice> uploadByteDevice;
206     QIODevice *outgoingData;
207     QSharedPointer<QRingBuffer> outgoingDataBuffer;
208     void emitReplyUploadProgress(qint64 bytesSent, qint64 bytesTotal); // dup?
209     qint64 bytesUploaded;
210
211
212     // cache
213     void createCache();
214     void completeCacheSave();
215     void setCachingEnabled(bool enable);
216     bool isCachingEnabled() const;
217     void initCacheSaveDevice();
218     QIODevice *cacheLoadDevice;
219     bool loadingFromCache;
220
221     QIODevice *cacheSaveDevice;
222     bool cacheEnabled; // is this for saving?
223
224
225     QUrl urlForLastAuthentication;
226 #ifndef QT_NO_NETWORKPROXY
227     QNetworkProxy lastProxyAuthentication;
228 #endif
229
230
231     bool migrateBackend();
232     bool canResume() const;
233     void setResumeOffset(quint64 offset);
234     quint64 resumeOffset;
235     qint64 preMigrationDownloaded;
236
237     // Used for normal downloading. For "zero copy" the downloadZerocopyBuffer is used
238     QByteDataBuffer downloadMultiBuffer;
239     QByteDataBuffer pendingDownloadData; // For signal compression
240     qint64 bytesDownloaded;
241
242     // only used when the "zero copy" style is used. Else downloadMultiBuffer is used.
243     // Please note that the whole "zero copy" download buffer API is private right now. Do not use it.
244     qint64 downloadBufferReadPosition;
245     qint64 downloadBufferCurrentSize;
246     QSharedPointer<char> downloadBufferPointer;
247     char* downloadZerocopyBuffer;
248
249     // Will be increased by HTTP thread:
250     QSharedPointer<QAtomicInt> pendingDownloadDataEmissions;
251     QSharedPointer<QAtomicInt> pendingDownloadProgressEmissions;
252
253
254 #ifndef QT_NO_SSL
255     QSslConfiguration sslConfiguration;
256     bool pendingIgnoreAllSslErrors;
257     QList<QSslError> pendingIgnoreSslErrorsList;
258 #endif
259
260
261     bool loadFromCacheIfAllowed(QHttpNetworkRequest &httpRequest);
262     void invalidateCache();
263     bool sendCacheContents(const QNetworkCacheMetaData &metaData);
264     QNetworkCacheMetaData fetchCacheMetaData(const QNetworkCacheMetaData &metaData) const;
265
266
267     void postRequest();
268
269
270
271 public:
272     // From HTTP thread:
273     void replyDownloadData(QByteArray);
274     void replyFinished();
275     void replyDownloadMetaData(QList<QPair<QByteArray,QByteArray> >,int,QString,bool,QSharedPointer<char>,qint64);
276     void replyDownloadProgressSlot(qint64,qint64);
277     void httpAuthenticationRequired(const QHttpNetworkRequest &request, QAuthenticator *auth);
278     void httpError(QNetworkReply::NetworkError error, const QString &errorString);
279 #ifndef QT_NO_SSL
280     void replySslErrors(const QList<QSslError> &, bool *, QList<QSslError> *);
281     void replySslConfigurationChanged(const QSslConfiguration&);
282 #endif
283 #ifndef QT_NO_NETWORKPROXY
284     void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *auth);
285 #endif
286
287     // From QNonContiguousByteDeviceThreadForwardImpl in HTTP thread:
288     void resetUploadDataSlot(bool *r);
289     void wantUploadDataSlot(qint64);
290     void sentUploadDataSlot(qint64);
291
292     Q_DECLARE_PUBLIC(QNetworkReplyHttpImpl)
293 };
294
295 QT_END_NAMESPACE
296
297 #endif // QT_NO_HTTP
298
299 #endif