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 QHTTPNETWORKCONNECTION_H
43 #define QHTTPNETWORKCONNECTION_H
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.
55 #include <QtNetwork/qnetworkrequest.h>
56 #include <QtNetwork/qnetworkreply.h>
57 #include <QtNetwork/qabstractsocket.h>
58 #include <QtNetwork/qnetworksession.h>
60 #include <private/qobject_p.h>
61 #include <qauthenticator.h>
62 #include <qnetworkproxy.h>
66 #include <private/qhttpnetworkheader_p.h>
67 #include <private/qhttpnetworkrequest_p.h>
68 #include <private/qhttpnetworkreply_p.h>
70 #include <private/qhttpnetworkconnectionchannel_p.h>
75 # include <QtNetwork/qsslsocket.h>
76 # include <QtNetwork/qsslerror.h>
78 # include <QtNetwork/qtcpsocket.h>
83 class QHttpNetworkRequest;
84 class QHttpNetworkReply;
88 class QHttpNetworkConnectionPrivate;
89 class Q_AUTOTEST_EXPORT QHttpNetworkConnection : public QObject
94 #ifndef QT_NO_BEARERMANAGEMENT
95 QHttpNetworkConnection(const QString &hostName, quint16 port = 80, bool encrypt = false, QObject *parent = 0, QSharedPointer<QNetworkSession> networkSession = QSharedPointer<QNetworkSession>());
96 QHttpNetworkConnection(quint16 channelCount, const QString &hostName, quint16 port = 80, bool encrypt = false, QObject *parent = 0, QSharedPointer<QNetworkSession> networkSession = QSharedPointer<QNetworkSession>());
98 QHttpNetworkConnection(const QString &hostName, quint16 port = 80, bool encrypt = false, QObject *parent = 0);
99 QHttpNetworkConnection(quint16 channelCount, const QString &hostName, quint16 port = 80, bool encrypt = false, QObject *parent = 0);
101 ~QHttpNetworkConnection();
103 //The hostname to which this is connected to.
104 QString hostName() const;
105 //The HTTP port in use.
106 quint16 port() const;
108 //add a new HTTP request through this connection
109 QHttpNetworkReply* sendRequest(const QHttpNetworkRequest &request);
111 #ifndef QT_NO_NETWORKPROXY
112 //set the proxy for this connection
113 void setCacheProxy(const QNetworkProxy &networkProxy);
114 QNetworkProxy cacheProxy() const;
115 void setTransparentProxy(const QNetworkProxy &networkProxy);
116 QNetworkProxy transparentProxy() const;
121 QHttpNetworkConnectionChannel *channels() const;
124 void setSslConfiguration(const QSslConfiguration &config);
125 void ignoreSslErrors(int channel = -1);
126 void ignoreSslErrors(const QList<QSslError> &errors, int channel = -1);
130 Q_DECLARE_PRIVATE(QHttpNetworkConnection)
131 Q_DISABLE_COPY(QHttpNetworkConnection)
132 friend class QHttpNetworkReply;
133 friend class QHttpNetworkReplyPrivate;
134 friend class QHttpNetworkConnectionChannel;
136 Q_PRIVATE_SLOT(d_func(), void _q_startNextRequest())
137 Q_PRIVATE_SLOT(d_func(), void _q_hostLookupFinished(QHostInfo))
138 Q_PRIVATE_SLOT(d_func(), void _q_connectDelayedChannel())
143 typedef QPair<QHttpNetworkRequest, QHttpNetworkReply*> HttpMessagePair;
146 class QHttpNetworkConnectionPrivate : public QObjectPrivate
148 Q_DECLARE_PUBLIC(QHttpNetworkConnection)
150 static const int defaultChannelCount;
151 static const int defaultPipelineLength;
152 static const int defaultRePipelineLength;
154 enum ConnectionState {
159 enum NetworkLayerPreferenceState {
166 QHttpNetworkConnectionPrivate(const QString &hostName, quint16 port, bool encrypt);
167 QHttpNetworkConnectionPrivate(quint16 channelCount, const QString &hostName, quint16 port, bool encrypt);
168 ~QHttpNetworkConnectionPrivate();
171 void pauseConnection();
172 void resumeConnection();
173 ConnectionState state;
174 NetworkLayerPreferenceState networkLayerState;
176 enum { ChunkSize = 4096 };
178 int indexOf(QAbstractSocket *socket) const;
180 QHttpNetworkReply *queueRequest(const QHttpNetworkRequest &request);
181 void requeueRequest(const HttpMessagePair &pair); // e.g. after pipeline broke
182 bool dequeueRequest(QAbstractSocket *socket);
183 void prepareRequest(HttpMessagePair &request);
184 QHttpNetworkRequest predictNextRequest();
186 void fillPipeline(QAbstractSocket *socket);
187 bool fillPipeline(QList<HttpMessagePair> &queue, QHttpNetworkConnectionChannel &channel);
189 // read more HTTP body after the next event loop spin
190 void readMoreLater(QHttpNetworkReply *reply);
192 void copyCredentials(int fromChannel, QAuthenticator *auth, bool isProxy);
194 void startHostInfoLookup();
195 void startNetworkLayerStateLookup();
196 void networkLayerDetected(QAbstractSocket::NetworkLayerProtocol protocol);
199 void _q_startNextRequest(); // send the next request from the queue
201 void _q_hostLookupFinished(QHostInfo info);
202 void _q_connectDelayedChannel();
204 void createAuthorization(QAbstractSocket *socket, QHttpNetworkRequest &request);
206 QString errorDetail(QNetworkReply::NetworkError errorCode, QAbstractSocket *socket,
207 const QString &extraDetail = QString());
209 void removeReply(QHttpNetworkReply *reply);
216 const int channelCount;
217 QTimer delayedConnectionTimer;
218 QHttpNetworkConnectionChannel *channels; // parallel connections to the server
219 bool shouldEmitChannelError(QAbstractSocket *socket);
221 qint64 uncompressedBytesAvailable(const QHttpNetworkReply &reply) const;
222 qint64 uncompressedBytesAvailableNextBlock(const QHttpNetworkReply &reply) const;
225 void emitReplyError(QAbstractSocket *socket, QHttpNetworkReply *reply, QNetworkReply::NetworkError errorCode);
226 bool handleAuthenticateChallenge(QAbstractSocket *socket, QHttpNetworkReply *reply, bool isProxy, bool &resend);
228 #ifndef QT_NO_NETWORKPROXY
229 QNetworkProxy networkProxy;
230 void emitProxyAuthenticationRequired(const QHttpNetworkConnectionChannel *chan, const QNetworkProxy &proxy, QAuthenticator* auth);
234 QList<HttpMessagePair> highPriorityQueue;
235 QList<HttpMessagePair> lowPriorityQueue;
237 #ifndef QT_NO_BEARERMANAGEMENT
238 QSharedPointer<QNetworkSession> networkSession;
241 friend class QHttpNetworkConnectionChannel;