summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarkus Goetz <Markus.Goetz@nokia.com>2010-02-17 16:36:40 +0100
committerMarkus Goetz <Markus.Goetz@nokia.com>2010-02-18 11:34:48 +0100
commita4332ce058cf3fe567b386d300ba740442a69f44 (patch)
tree3d51bb57f5dc434ded41e03a7ef80cc90058d367
parent4971430290ecb11012ef5cbf8ef041da0ec3a824 (diff)
QNAM HTTP: Always set channel.reply to 0 when done
This will help us to track down a sporadic bug that made requests being sent again even if they were already done. Reviewed-by: Peter Hartmann
-rw-r--r--src/network/access/qhttpnetworkconnection.cpp12
-rw-r--r--src/network/access/qhttpnetworkconnection_p.h5
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel.cpp17
-rw-r--r--src/network/access/qhttpnetworkreply.cpp13
-rw-r--r--src/network/access/qhttpnetworkreply_p.h2
5 files changed, 27 insertions, 22 deletions
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
index cc6a1c8caa..327d2dbcf4 100644
--- a/src/network/access/qhttpnetworkconnection.cpp
+++ b/src/network/access/qhttpnetworkconnection.cpp
@@ -404,6 +404,7 @@ QHttpNetworkReply* QHttpNetworkConnectionPrivate::queueRequest(const QHttpNetwor
QHttpNetworkReply *reply = new QHttpNetworkReply(request.url());
reply->setRequest(request);
reply->d_func()->connection = q;
+ reply->d_func()->connectionChannel = &channels[0]; // will have the correct one set later
HttpMessagePair pair = qMakePair(request, reply);
switch (request.priority()) {
@@ -861,17 +862,6 @@ QNetworkProxy QHttpNetworkConnection::transparentProxy() const
// SSL support below
#ifndef QT_NO_OPENSSL
-QSslConfiguration QHttpNetworkConnectionPrivate::sslConfiguration(const QHttpNetworkReply &reply) const
-{
- if (!encrypt)
- return QSslConfiguration();
-
- for (int i = 0; i < channelCount; ++i)
- if (channels[i].reply == &reply)
- return static_cast<QSslSocket *>(channels[0].socket)->sslConfiguration();
- return QSslConfiguration(); // pending or done request
-}
-
void QHttpNetworkConnection::setSslConfiguration(const QSslConfiguration &config)
{
Q_D(QHttpNetworkConnection);
diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h
index 03cf09cb5c..823774e6c9 100644
--- a/src/network/access/qhttpnetworkconnection_p.h
+++ b/src/network/access/qhttpnetworkconnection_p.h
@@ -210,11 +210,6 @@ public:
void emitReplyError(QAbstractSocket *socket, QHttpNetworkReply *reply, QNetworkReply::NetworkError errorCode);
bool handleAuthenticateChallenge(QAbstractSocket *socket, QHttpNetworkReply *reply, bool isProxy, bool &resend);
-
-#ifndef QT_NO_OPENSSL
- QSslConfiguration sslConfiguration(const QHttpNetworkReply &reply) const;
-#endif
-
#ifndef QT_NO_NETWORKPROXY
QNetworkProxy networkProxy;
void emitProxyAuthenticationRequired(const QHttpNetworkConnectionChannel *chan, const QNetworkProxy &proxy, QAuthenticator* auth);
diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
index 2a3036b7f8..89fd03252c 100644
--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
+++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
@@ -137,6 +137,7 @@ bool QHttpNetworkConnectionChannel::sendRequest()
if (reply) {
reply->d_func()->clear();
reply->d_func()->connection = connection;
+ reply->d_func()->connectionChannel = this;
reply->d_func()->autoDecompress = request.d->autoDecompress;
reply->d_func()->pipeliningUsed = false;
}
@@ -568,7 +569,8 @@ void QHttpNetworkConnectionChannel::allDone()
handleStatus();
// ### at this point there should be no more data on the socket
// close if server requested
- if (reply->d_func()->isConnectionCloseEnabled())
+ bool connectionCloseEnabled = reply->d_func()->isConnectionCloseEnabled();
+ if (connectionCloseEnabled)
close();
// queue the finished signal, this is required since we might send new requests from
// slot connected to it. The socket will not fire readyRead signal, if we are already
@@ -579,14 +581,22 @@ void QHttpNetworkConnectionChannel::allDone()
// in case of failures, each channel will attempt two reconnects before emitting error.
reconnectAttempts = 2;
+ detectPipeliningSupport();
+
// now the channel can be seen as free/idle again, all signal emissions for the reply have been done
this->state = QHttpNetworkConnectionChannel::IdleState;
- detectPipeliningSupport();
+ // if it does not need to be sent again we can set it to 0
+ // the previous code did not do that and we had problems with accidental re-sending of a
+ // finished request.
+ // Note that this may trigger a segfault at some other point. But then we can fix the underlying
+ // problem.
+ if (!resendCurrent)
+ reply = 0;
// move next from pipeline to current request
if (!alreadyPipelinedRequests.isEmpty()) {
- if (resendCurrent || reply->d_func()->isConnectionCloseEnabled() || socket->state() != QAbstractSocket::ConnectedState) {
+ if (resendCurrent || connectionCloseEnabled || socket->state() != QAbstractSocket::ConnectedState) {
// move the pipelined ones back to the main queue
requeueCurrentlyPipelinedRequests();
close();
@@ -745,6 +755,7 @@ void QHttpNetworkConnectionChannel::pipelineInto(HttpMessagePair &pair)
if (reply) {
reply->d_func()->clear();
reply->d_func()->connection = connection;
+ reply->d_func()->connectionChannel = this;
reply->d_func()->autoDecompress = request.d->autoDecompress;
reply->d_func()->pipeliningUsed = true;
}
diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp
index 512c04597a..984f557164 100644
--- a/src/network/access/qhttpnetworkreply.cpp
+++ b/src/network/access/qhttpnetworkreply.cpp
@@ -230,6 +230,7 @@ void QHttpNetworkReplyPrivate::clear()
currentChunkRead = 0;
connectionCloseEnabled = true;
connection = 0;
+ connectionChannel = 0;
#ifndef QT_NO_COMPRESS
if (initInflate)
inflateEnd(&inflateStrm);
@@ -803,9 +804,15 @@ void QHttpNetworkReplyPrivate::eraseData()
QSslConfiguration QHttpNetworkReply::sslConfiguration() const
{
Q_D(const QHttpNetworkReply);
- if (d->connection)
- return d->connection->d_func()->sslConfiguration(*this);
- return QSslConfiguration();
+
+ if (!d->connectionChannel)
+ return QSslConfiguration();
+
+ QSslSocket *sslSocket = qobject_cast<QSslSocket*>(d->connectionChannel->socket);
+ if (!sslSocket)
+ return QSslConfiguration();
+
+ return sslSocket->sslConfiguration();
}
void QHttpNetworkReply::setSslConfiguration(const QSslConfiguration &config)
diff --git a/src/network/access/qhttpnetworkreply_p.h b/src/network/access/qhttpnetworkreply_p.h
index af9266b033..fa240ece38 100644
--- a/src/network/access/qhttpnetworkreply_p.h
+++ b/src/network/access/qhttpnetworkreply_p.h
@@ -86,6 +86,7 @@ static const unsigned char gz_magic[2] = {0x1f, 0x8b}; // gzip magic header
QT_BEGIN_NAMESPACE
class QHttpNetworkConnection;
+class QHttpNetworkConnectionChannel;
class QHttpNetworkRequest;
class QHttpNetworkConnectionPrivate;
class QHttpNetworkReplyPrivate;
@@ -218,6 +219,7 @@ public:
qint64 currentChunkSize;
qint64 currentChunkRead;
QPointer<QHttpNetworkConnection> connection;
+ QPointer<QHttpNetworkConnectionChannel> connectionChannel;
bool initInflate;
bool streamEnd;
#ifndef QT_NO_COMPRESS