1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtNetwork module of the Qt Toolkit.
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.
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.
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.
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.
40 ****************************************************************************/
42 #ifndef QHTTPTHREADDELEGATE_H
43 #define QHTTPTHREADDELEGATE_H
50 // This file is not part of the Qt API. It exists for the convenience
51 // of the Network Access API. This header file may change from
52 // version to version without notice, or even be removed.
58 #include <QThreadStorage>
59 #include <QNetworkProxy>
60 #include <QSslConfiguration>
63 #include <QNetworkReply>
64 #include "qhttpnetworkrequest_p.h"
65 #include "qhttpnetworkconnection_p.h"
66 #include <QSharedPointer>
67 #include "qsslconfiguration.h"
68 #include "private/qnoncontiguousbytedevice_p.h"
69 #include "qnetworkaccessauthenticationmanager_p.h"
76 class QHttpNetworkReply;
78 class QNetworkAccessCache;
79 class QNetworkAccessCachedHttpConnection;
81 class QHttpThreadDelegate : public QObject
85 explicit QHttpThreadDelegate(QObject *parent = 0);
87 ~QHttpThreadDelegate();
92 QSslConfiguration incomingSslConfiguration;
94 QHttpNetworkRequest httpRequest;
95 qint64 downloadBufferMaximumSize;
96 qint64 readBufferMaxSize;
98 // From backend, modified by us for signal compression
99 QSharedPointer<QAtomicInt> pendingDownloadData;
100 QSharedPointer<QAtomicInt> pendingDownloadProgress;
101 #ifndef QT_NO_NETWORKPROXY
102 QNetworkProxy cacheProxy;
103 QNetworkProxy transparentProxy;
105 QSharedPointer<QNetworkAccessAuthenticationManager> authenticationManager;
108 // outgoing, Retrieved in the synchronous HTTP case
109 QByteArray synchronousDownloadData;
110 QList<QPair<QByteArray,QByteArray> > incomingHeaders;
111 int incomingStatusCode;
112 QString incomingReasonPhrase;
113 bool isPipeliningUsed;
114 qint64 incomingContentLength;
115 QNetworkReply::NetworkError incomingErrorCode;
116 QString incomingErrorDetail;
117 #ifndef QT_NO_BEARERMANAGEMENT
118 QSharedPointer<QNetworkSession> networkSession;
122 // The zerocopy download buffer, if used:
123 QSharedPointer<char> downloadBuffer;
124 // The QHttpNetworkConnection that is used
125 QNetworkAccessCachedHttpConnection *httpConnection;
127 QHttpNetworkReply *httpReply;
129 // Used for implementing the synchronous HTTP, see startRequestSynchronously()
130 QEventLoop *synchronousRequestLoop;
133 void authenticationRequired(const QHttpNetworkRequest &request, QAuthenticator *);
134 #ifndef QT_NO_NETWORKPROXY
135 void proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *);
138 void sslErrors(const QList<QSslError> &, bool *, QList<QSslError> *);
139 void sslConfigurationChanged(const QSslConfiguration);
141 void downloadMetaData(QList<QPair<QByteArray,QByteArray> >,int,QString,bool,QSharedPointer<char>,qint64);
142 void downloadProgress(qint64, qint64);
143 void downloadData(QByteArray);
144 void error(QNetworkReply::NetworkError, const QString);
145 void downloadFinished();
147 // This are called via QueuedConnection from user thread
150 void readBufferSizeChanged(qint64 size);
151 void readBufferFreed(qint64 size);
153 // This is called with a BlockingQueuedConnection from user thread
154 void startRequestSynchronously();
157 void readyReadSlot();
159 void finishedWithErrorSlot(QNetworkReply::NetworkError errorCode, const QString &detail = QString());
160 void synchronousFinishedSlot();
161 void synchronousFinishedWithErrorSlot(QNetworkReply::NetworkError errorCode, const QString &detail = QString());
162 void headerChangedSlot();
163 void synchronousHeaderChangedSlot();
164 void dataReadProgressSlot(qint64 done, qint64 total);
165 void cacheCredentialsSlot(const QHttpNetworkRequest &request, QAuthenticator *authenticator);
167 void sslErrorsSlot(const QList<QSslError> &errors);
170 void synchronousAuthenticationRequiredSlot(const QHttpNetworkRequest &request, QAuthenticator *);
171 #ifndef QT_NO_NETWORKPROXY
172 void synchronousProxyAuthenticationRequiredSlot(const QNetworkProxy &, QAuthenticator *);
176 // Cache for all the QHttpNetworkConnection objects.
177 // This is per thread.
178 static QThreadStorage<QNetworkAccessCache *> connections;
182 // This QNonContiguousByteDevice is connected to the QNetworkAccessHttpBackend
183 // and represents the PUT/POST data.
184 class QNonContiguousByteDeviceThreadForwardImpl : public QNonContiguousByteDevice
188 bool wantDataPending;
191 QByteArray m_dataArray;
195 QNonContiguousByteDeviceThreadForwardImpl(bool aE, qint64 s)
196 : QNonContiguousByteDevice(),
197 wantDataPending(false),
205 ~QNonContiguousByteDeviceThreadForwardImpl()
209 const char* readPointer(qint64 maximumLength, qint64 &len)
218 } else if (!wantDataPending) {
220 wantDataPending = true;
221 emit wantData(maximumLength);
223 // Do nothing, we already sent a wantData signal and wait for results
229 bool advanceReadPointer(qint64 a)
237 // To main thread to inform about our state
238 emit processedData(a);
240 // FIXME possible optimization, already ask user thread for some data
258 // Communicate as BlockingQueuedConnection
271 void haveDataSlot(QByteArray dataArray, bool dataAtEnd, qint64 dataSize)
273 wantDataPending = false;
275 m_dataArray = dataArray;
276 m_data = const_cast<char*>(m_dataArray.constData());
277 m_amount = dataArray.size();
282 // This will tell the HTTP code (QHttpNetworkConnectionChannel) that we have data available now
287 // void readyRead(); in parent class
288 // void readProgress(qint64 current, qint64 total); happens in the main thread with the real bytedevice
291 void wantData(qint64);
292 void processedData(qint64);
293 void resetData(bool *b);
300 #endif // QHTTPTHREADDELEGATE_H