summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel.cpp44
1 files changed, 23 insertions, 21 deletions
diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
index 646ede0022..d8ce28a7b0 100644
--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
+++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
@@ -44,6 +44,7 @@
#include <qpair.h>
#include <qdebug.h>
+#include <QScopedValueRollback>
#ifndef QT_NO_HTTP
@@ -196,41 +197,42 @@ void QHttpNetworkConnectionChannel::init()
void QHttpNetworkConnectionChannel::close()
{
- if (!socket)
- state = QHttpNetworkConnectionChannel::IdleState;
- else if (socket->state() == QAbstractSocket::UnconnectedState)
- state = QHttpNetworkConnectionChannel::IdleState;
- else
- state = QHttpNetworkConnectionChannel::ClosingState;
-
+ // socket can be 0 since the host lookup is done from qhttpnetworkconnection.cpp while
+ // there is no socket yet; we may also clear it, below or in abort, to avoid recursion.
+ const bool idle = !socket || socket->state() == QAbstractSocket::UnconnectedState;
+ const ChannelState final = idle ? IdleState : ClosingState;
// pendingEncrypt must only be true in between connected and encrypted states
pendingEncrypt = false;
if (socket) {
- // socket can be 0 since the host lookup is done from qhttpnetworkconnection.cpp while
- // there is no socket yet.
- socket->close();
+ QAbstractSocket *const detached = socket;
+ QScopedValueRollback<QAbstractSocket *> rollback(socket, nullptr);
+ state = final; // Needed during close(), which may over-write it.
+ detached->close(); // Error states can cause recursion back to this method.
}
-}
+ // Set state *after* close(), to override any recursive call's idle setting:
+ state = final;
+}
void QHttpNetworkConnectionChannel::abort()
{
- if (!socket)
- state = QHttpNetworkConnectionChannel::IdleState;
- else if (socket->state() == QAbstractSocket::UnconnectedState)
- state = QHttpNetworkConnectionChannel::IdleState;
- else
- state = QHttpNetworkConnectionChannel::ClosingState;
-
+ // socket can be 0 since the host lookup is done from qhttpnetworkconnection.cpp while
+ // there is no socket yet; we may also clear it, below or in close, to avoid recursion.
+ const bool idle = !socket || socket->state() == QAbstractSocket::UnconnectedState;
+ const ChannelState final = idle ? IdleState : ClosingState;
// pendingEncrypt must only be true in between connected and encrypted states
pendingEncrypt = false;
if (socket) {
- // socket can be 0 since the host lookup is done from qhttpnetworkconnection.cpp while
- // there is no socket yet.
- socket->abort();
+ QAbstractSocket *const detached = socket;
+ QScopedValueRollback<QAbstractSocket *> rollback(socket, nullptr);
+ state = final;
+ detached->abort();
}
+
+ // Set state *after* abort(), to override any recursive call's idle setting:
+ state = final;
}