summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/network/access/qhttpnetworkconnection.cpp82
-rw-r--r--src/network/access/qhttpnetworkconnection_p.h15
2 files changed, 56 insertions, 41 deletions
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
index 32881b2..f8f7620 100644
--- a/src/network/access/qhttpnetworkconnection.cpp
+++ b/src/network/access/qhttpnetworkconnection.cpp
@@ -45,6 +45,7 @@
#include <private/qnetworkrequest_p.h>
#include <private/qobject_p.h>
#include <private/qauthenticator_p.h>
+#include <private/qabstractsocket_p.h>
#include <qnetworkproxy.h>
#include <qauthenticator.h>
@@ -56,6 +57,7 @@
#ifndef QT_NO_HTTP
#ifndef QT_NO_OPENSSL
+# include <private/qsslsocket_p.h>
# include <QtNetwork/qsslkey.h>
# include <QtNetwork/qsslcipher.h>
# include <QtNetwork/qsslconfiguration.h>
@@ -79,9 +81,9 @@ const int QHttpNetworkConnectionPrivate::defaultRePipelineLength = 2;
QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(const QString &hostName, quint16 port, bool encrypt)
-: hostName(hostName), port(port), encrypt(encrypt),
- channelCount(defaultChannelCount),
- pendingAuthSignal(false), pendingProxyAuthSignal(false)
+: state(RunningState),
+ hostName(hostName), port(port), encrypt(encrypt),
+ channelCount(defaultChannelCount)
#ifndef QT_NO_NETWORKPROXY
, networkProxy(QNetworkProxy::NoProxy)
#endif
@@ -90,9 +92,9 @@ QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(const QString &host
}
QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(quint16 channelCount, const QString &hostName, quint16 port, bool encrypt)
-: hostName(hostName), port(port), encrypt(encrypt),
- channelCount(channelCount),
- pendingAuthSignal(false), pendingProxyAuthSignal(false)
+: state(RunningState),
+ hostName(hostName), port(port), encrypt(encrypt),
+ channelCount(channelCount)
#ifndef QT_NO_NETWORKPROXY
, networkProxy(QNetworkProxy::NoProxy)
#endif
@@ -121,6 +123,37 @@ void QHttpNetworkConnectionPrivate::init()
}
}
+void QHttpNetworkConnectionPrivate::pauseConnection()
+{
+ state = PausedState;
+
+ // Disable all socket notifiers
+ for (int i = 0; i < channelCount; i++) {
+ if (encrypt)
+ QSslSocketPrivate::pauseSocketNotifiers(static_cast<QSslSocket*>(channels[i].socket));
+ else
+ QAbstractSocketPrivate::pauseSocketNotifiers(channels[i].socket);
+ }
+}
+
+void QHttpNetworkConnectionPrivate::resumeConnection()
+{
+ state = RunningState;
+ // Enable all socket notifiers
+ for (int i = 0; i < channelCount; i++) {
+ if (encrypt)
+ QSslSocketPrivate::resumeSocketNotifiers(static_cast<QSslSocket*>(channels[i].socket));
+ else
+ QAbstractSocketPrivate::resumeSocketNotifiers(channels[i].socket);
+ }
+
+ // Resume uploads
+ // FIXME
+
+ // queue _q_startNextRequest
+ QMetaObject::invokeMethod(this->q_func(), "_q_startNextRequest", Qt::QueuedConnection);
+}
+
int QHttpNetworkConnectionPrivate::indexOf(QAbstractSocket *socket) const
{
for (int i = 0; i < channelCount; ++i)
@@ -315,35 +348,19 @@ bool QHttpNetworkConnectionPrivate::handleAuthenticateChallenge(QAbstractSocket
priv->parseHttpResponse(fields, isProxy);
if (priv->phase == QAuthenticatorPrivate::Done) {
- if ((isProxy && pendingProxyAuthSignal) ||(!isProxy && pendingAuthSignal)) {
- // drop the request
- reply->d_func()->eraseData();
- channels[i].close();
- channels[i].lastStatus = 0;
- channels[i].state = QHttpNetworkConnectionChannel::Wait4AuthState;
- return false;
- }
- // cannot use this socket until the slot returns
- channels[i].state = QHttpNetworkConnectionChannel::WaitingState;
- socket->blockSignals(true);
+ pauseConnection();
if (!isProxy) {
- pendingAuthSignal = true;
emit q->authenticationRequired(reply->request(), auth, q);
- pendingAuthSignal = false;
#ifndef QT_NO_NETWORKPROXY
} else {
- pendingProxyAuthSignal = true;
emit q->proxyAuthenticationRequired(networkProxy, auth, q);
- pendingProxyAuthSignal = false;
#endif
}
- socket->blockSignals(false);
- // socket free to use
- channels[i].state = QHttpNetworkConnectionChannel::IdleState;
+ resumeConnection();
+
if (priv->phase != QAuthenticatorPrivate::Done) {
// send any pending requests
copyCredentials(i, auth, isProxy);
- QMetaObject::invokeMethod(q, "_q_restartAuthPendingRequests", Qt::QueuedConnection);
}
}
// - Changing values in QAuthenticator will reset the 'phase'. Therefore if it is still "Done"
@@ -729,6 +746,10 @@ void QHttpNetworkConnectionPrivate::removeReply(QHttpNetworkReply *reply)
// although it is called _q_startNextRequest, it will actually start multiple requests when possible
void QHttpNetworkConnectionPrivate::_q_startNextRequest()
{
+ // If the QHttpNetworkConnection is currently paused then bail out immediatly
+ if (state == PausedState)
+ return;
+
//resend the necessary ones.
for (int i = 0; i < channelCount; ++i) {
if (channels[i].resendCurrent) {
@@ -779,17 +800,6 @@ void QHttpNetworkConnectionPrivate::_q_startNextRequest()
fillPipeline(channels[i].socket);
}
-void QHttpNetworkConnectionPrivate::_q_restartAuthPendingRequests()
-{
- // send the request using the idle socket
- for (int i = 0 ; i < channelCount; ++i) {
- if (channels[i].state == QHttpNetworkConnectionChannel::Wait4AuthState) {
- channels[i].state = QHttpNetworkConnectionChannel::IdleState;
- if (channels[i].reply)
- channels[i].sendRequest();
- }
- }
-}
void QHttpNetworkConnectionPrivate::readMoreLater(QHttpNetworkReply *reply)
{
diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h
index 51666d6..f2e0b1c 100644
--- a/src/network/access/qhttpnetworkconnection_p.h
+++ b/src/network/access/qhttpnetworkconnection_p.h
@@ -141,10 +141,10 @@ private:
Q_DECLARE_PRIVATE(QHttpNetworkConnection)
Q_DISABLE_COPY(QHttpNetworkConnection)
friend class QHttpNetworkReply;
+ friend class QHttpNetworkReplyPrivate;
friend class QHttpNetworkConnectionChannel;
Q_PRIVATE_SLOT(d_func(), void _q_startNextRequest())
- Q_PRIVATE_SLOT(d_func(), void _q_restartAuthPendingRequests())
};
@@ -160,11 +160,20 @@ public:
static const int defaultPipelineLength;
static const int defaultRePipelineLength;
+ enum ConnectionState {
+ RunningState = 0,
+ PausedState = 1,
+ };
+
QHttpNetworkConnectionPrivate(const QString &hostName, quint16 port, bool encrypt);
QHttpNetworkConnectionPrivate(quint16 channelCount, const QString &hostName, quint16 port, bool encrypt);
~QHttpNetworkConnectionPrivate();
void init();
+ void pauseConnection();
+ void resumeConnection();
+ ConnectionState state;
+
enum { ChunkSize = 4096 };
int indexOf(QAbstractSocket *socket) const;
@@ -184,7 +193,6 @@ public:
// private slots
void _q_startNextRequest(); // send the next request from the queue
- void _q_restartAuthPendingRequests(); // send the currently blocked request
void createAuthorization(QAbstractSocket *socket, QHttpNetworkRequest &request);
@@ -203,9 +211,6 @@ public:
const int channelCount;
QHttpNetworkConnectionChannel *channels; // parallel connections to the server
- bool pendingAuthSignal; // there is an incomplete authentication signal
- bool pendingProxyAuthSignal; // there is an incomplete proxy authentication signal
-
qint64 uncompressedBytesAvailable(const QHttpNetworkReply &reply) const;
qint64 uncompressedBytesAvailableNextBlock(const QHttpNetworkReply &reply) const;