diff options
Diffstat (limited to 'src/network')
-rw-r--r-- | src/network/access/qnetworkaccessmanager.cpp | 103 | ||||
-rw-r--r-- | src/network/access/qnetworkaccessmanager.h | 2 | ||||
-rw-r--r-- | src/network/access/qnetworkaccessmanager_p.h | 5 | ||||
-rw-r--r-- | src/network/doc/qtnetwork.qdocconf | 2 | ||||
-rw-r--r-- | src/network/kernel/qauthenticator.cpp | 2 | ||||
-rw-r--r-- | src/network/socket/qlocalsocket_p.h | 2 | ||||
-rw-r--r-- | src/network/socket/qlocalsocket_win.cpp | 6 | ||||
-rw-r--r-- | src/network/socket/qnativesocketengine_winrt.cpp | 34 | ||||
-rw-r--r-- | src/network/socket/qnativesocketengine_winrt_p.h | 2 | ||||
-rw-r--r-- | src/network/ssl/qsslconfiguration.cpp | 2 | ||||
-rw-r--r-- | src/network/ssl/qsslconfiguration_p.h | 1 |
11 files changed, 120 insertions, 41 deletions
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index d2b1a8a912..927e103abc 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -480,6 +480,9 @@ QNetworkAccessManager::QNetworkAccessManager(QObject *parent) // connect(&d->networkConfigurationManager, SIGNAL(onlineStateChanged(bool)), SLOT(_q_onlineStateChanged(bool))); + connect(&d->networkConfigurationManager, SIGNAL(configurationChanged(const QNetworkConfiguration &)), + SLOT(_q_configurationChanged(const QNetworkConfiguration &))); + #endif } @@ -1570,6 +1573,8 @@ void QNetworkAccessManagerPrivate::createSession(const QNetworkConfiguration &co QObject::disconnect(networkSessionStrongRef.data(), SIGNAL(closed()), q, SLOT(_q_networkSessionClosed())); QObject::disconnect(networkSessionStrongRef.data(), SIGNAL(stateChanged(QNetworkSession::State)), q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State))); + QObject::disconnect(networkSessionStrongRef.data(), SIGNAL(error(QNetworkSession::SessionError)), + q, SLOT(_q_networkSessionFailed(QNetworkSession::SessionError))); } //switch to new session (null if config was invalid) @@ -1577,7 +1582,6 @@ void QNetworkAccessManagerPrivate::createSession(const QNetworkConfiguration &co networkSessionWeakRef = networkSessionStrongRef.toWeakRef(); if (!networkSessionStrongRef) { - online = false; if (networkAccessible == QNetworkAccessManager::NotAccessible || !online) emit q->networkAccessibleChanged(QNetworkAccessManager::NotAccessible); @@ -1593,6 +1597,8 @@ void QNetworkAccessManagerPrivate::createSession(const QNetworkConfiguration &co QObject::connect(networkSessionStrongRef.data(), SIGNAL(closed()), q, SLOT(_q_networkSessionClosed()), Qt::QueuedConnection); QObject::connect(networkSessionStrongRef.data(), SIGNAL(stateChanged(QNetworkSession::State)), q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State)), Qt::QueuedConnection); + QObject::connect(networkSessionStrongRef.data(), SIGNAL(error(QNetworkSession::SessionError)), + q, SLOT(_q_networkSessionFailed(QNetworkSession::SessionError))); _q_networkSessionStateChanged(networkSessionStrongRef->state()); } @@ -1609,6 +1615,9 @@ void QNetworkAccessManagerPrivate::_q_networkSessionClosed() QObject::disconnect(networkSession.data(), SIGNAL(closed()), q, SLOT(_q_networkSessionClosed())); QObject::disconnect(networkSession.data(), SIGNAL(stateChanged(QNetworkSession::State)), q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State))); + QObject::disconnect(networkSessionStrongRef.data(), SIGNAL(error(QNetworkSession::SessionError)), + q, SLOT(_q_networkSessionFailed(QNetworkSession::SessionError))); + networkSessionStrongRef.clear(); networkSessionWeakRef.clear(); } @@ -1617,46 +1626,57 @@ void QNetworkAccessManagerPrivate::_q_networkSessionClosed() void QNetworkAccessManagerPrivate::_q_networkSessionStateChanged(QNetworkSession::State state) { Q_Q(QNetworkAccessManager); - + bool reallyOnline = false; //Do not emit the networkSessionConnected signal here, except for roaming -> connected //transition, otherwise it is emitted twice in a row when opening a connection. - if (state == QNetworkSession::Connected && lastSessionState == QNetworkSession::Roaming) + if (state == QNetworkSession::Connected && lastSessionState != QNetworkSession::Roaming) emit q->networkSessionConnected(); lastSessionState = state; - if (online) { + if (online && state == QNetworkSession::Disconnected) { + const auto cfgs = networkConfigurationManager.allConfigurations(); + for (const QNetworkConfiguration &cfg : cfgs) { + if (cfg.state().testFlag(QNetworkConfiguration::Active)) { + reallyOnline = true; + } + } + } else if (state == QNetworkSession::Connected || state == QNetworkSession::Roaming) { + reallyOnline = true; + } + + if (!reallyOnline) { if (state != QNetworkSession::Connected && state != QNetworkSession::Roaming) { - online = false; if (networkAccessible != QNetworkAccessManager::NotAccessible) { networkAccessible = QNetworkAccessManager::NotAccessible; emit q->networkAccessibleChanged(networkAccessible); } } } else { - if (state == QNetworkSession::Connected || state == QNetworkSession::Roaming) { - online = true; - if (defaultAccessControl) - if (networkAccessible != QNetworkAccessManager::Accessible) { - networkAccessible = QNetworkAccessManager::Accessible; - emit q->networkAccessibleChanged(networkAccessible); - } - } + if (defaultAccessControl) + if (networkAccessible != QNetworkAccessManager::Accessible) { + networkAccessible = QNetworkAccessManager::Accessible; + emit q->networkAccessibleChanged(networkAccessible); + } + } + online = reallyOnline; + if (online && (state != QNetworkSession::Connected && state != QNetworkSession::Roaming)) { + _q_networkSessionClosed(); + createSession(q->configuration()); } } void QNetworkAccessManagerPrivate::_q_onlineStateChanged(bool isOnline) { Q_Q(QNetworkAccessManager); + // if the user set a config, we only care whether this one is active. // Otherwise, this QNAM is online if there is an online config. if (customNetworkConfiguration) { online = (networkConfiguration.state() & QNetworkConfiguration::Active); } else { if (online != isOnline) { - if (isOnline) { - networkSessionStrongRef.clear(); - networkSessionWeakRef.clear(); - } + _q_networkSessionClosed(); + createSession(q->configuration()); online = isOnline; } } @@ -1667,11 +1687,6 @@ void QNetworkAccessManagerPrivate::_q_onlineStateChanged(bool isOnline) emit q->networkAccessibleChanged(networkAccessible); } } - } else if (networkConfiguration.state().testFlag(QNetworkConfiguration::Undefined)) { - if (networkAccessible != QNetworkAccessManager::UnknownAccessibility) { - networkAccessible = QNetworkAccessManager::UnknownAccessibility; - emit q->networkAccessibleChanged(networkAccessible); - } } else { if (networkAccessible != QNetworkAccessManager::NotAccessible) { networkAccessible = QNetworkAccessManager::NotAccessible; @@ -1680,6 +1695,50 @@ void QNetworkAccessManagerPrivate::_q_onlineStateChanged(bool isOnline) } } +void QNetworkAccessManagerPrivate::_q_configurationChanged(const QNetworkConfiguration &configuration) +{ + const QString id = configuration.identifier(); + if (configuration.state().testFlag(QNetworkConfiguration::Active)) { + if (!onlineConfigurations.contains(id)) { + + QSharedPointer<QNetworkSession> session(getNetworkSession()); + if (session) { + if (online && session->configuration().identifier() + != networkConfigurationManager.defaultConfiguration().identifier()) { + + onlineConfigurations.insert(id); + //this one disconnected but another one is online, + // close and create new session + _q_networkSessionClosed(); + createSession(networkConfigurationManager.defaultConfiguration()); + } + } + } + + } else if (onlineConfigurations.contains(id)) { + //this one is disconnecting + onlineConfigurations.remove(id); + if (!onlineConfigurations.isEmpty()) { + _q_networkSessionClosed(); + createSession(configuration); + } + } +} + + +void QNetworkAccessManagerPrivate::_q_networkSessionFailed(QNetworkSession::SessionError) +{ + const auto cfgs = networkConfigurationManager.allConfigurations(); + for (const QNetworkConfiguration &cfg : cfgs) { + if (cfg.state().testFlag(QNetworkConfiguration::Active)) { + online = true; + _q_networkSessionClosed(); + createSession(networkConfigurationManager.defaultConfiguration()); + return; + } + } +} + #endif // QT_NO_BEARERMANAGEMENT QNetworkRequest QNetworkAccessManagerPrivate::prepareMultipart(const QNetworkRequest &request, QHttpMultiPart *multiPart) diff --git a/src/network/access/qnetworkaccessmanager.h b/src/network/access/qnetworkaccessmanager.h index 4efa30df49..4ce47577c8 100644 --- a/src/network/access/qnetworkaccessmanager.h +++ b/src/network/access/qnetworkaccessmanager.h @@ -182,6 +182,8 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_networkSessionClosed()) Q_PRIVATE_SLOT(d_func(), void _q_networkSessionStateChanged(QNetworkSession::State)) Q_PRIVATE_SLOT(d_func(), void _q_onlineStateChanged(bool)) + Q_PRIVATE_SLOT(d_func(), void _q_configurationChanged(const QNetworkConfiguration &)) + Q_PRIVATE_SLOT(d_func(), void _q_networkSessionFailed(QNetworkSession::SessionError)) #endif }; diff --git a/src/network/access/qnetworkaccessmanager_p.h b/src/network/access/qnetworkaccessmanager_p.h index 413de2a4fe..44cf253368 100644 --- a/src/network/access/qnetworkaccessmanager_p.h +++ b/src/network/access/qnetworkaccessmanager_p.h @@ -149,6 +149,11 @@ public: bool isSeamless); void _q_networkSessionStateChanged(QNetworkSession::State state); void _q_onlineStateChanged(bool isOnline); + void _q_configurationChanged(const QNetworkConfiguration &configuration); + void _q_networkSessionFailed(QNetworkSession::SessionError error); + + QSet<QString> onlineConfigurations; + #endif QNetworkRequest prepareMultipart(const QNetworkRequest &request, QHttpMultiPart *multiPart); diff --git a/src/network/doc/qtnetwork.qdocconf b/src/network/doc/qtnetwork.qdocconf index 87e322d6c0..2a8e577dda 100644 --- a/src/network/doc/qtnetwork.qdocconf +++ b/src/network/doc/qtnetwork.qdocconf @@ -4,7 +4,7 @@ project = QtNetwork description = Qt Network Reference Documentation version = $QT_VERSION -examplesinstallpath = qtbase/network +examplesinstallpath = network qhp.projects = QtNetwork diff --git a/src/network/kernel/qauthenticator.cpp b/src/network/kernel/qauthenticator.cpp index 78753a7393..a73f01a2fc 100644 --- a/src/network/kernel/qauthenticator.cpp +++ b/src/network/kernel/qauthenticator.cpp @@ -199,6 +199,8 @@ bool QAuthenticator::operator==(const QAuthenticator &other) const { if (d == other.d) return true; + if (!d || !other.d) + return false; return d->user == other.d->user && d->password == other.d->password && d->realm == other.d->realm diff --git a/src/network/socket/qlocalsocket_p.h b/src/network/socket/qlocalsocket_p.h index cf36887e92..56f8b590f1 100644 --- a/src/network/socket/qlocalsocket_p.h +++ b/src/network/socket/qlocalsocket_p.h @@ -61,7 +61,6 @@ #if defined(QT_LOCALSOCKET_TCP) # include "qtcpsocket.h" #elif defined(Q_OS_WIN) -# include <private/qringbuffer_p.h> # include "private/qwindowspipereader_p.h" # include "private/qwindowspipewriter_p.h" # include <qwineventnotifier.h> @@ -134,7 +133,6 @@ public: void _q_pipeClosed(); void _q_winError(ulong windowsError, const QString &function); HANDLE handle; - QRingBuffer writeBuffer; QWindowsPipeWriter *pipeWriter; QWindowsPipeReader *pipeReader; QLocalSocket::LocalSocketError error; diff --git a/src/network/socket/qlocalsocket_win.cpp b/src/network/socket/qlocalsocket_win.cpp index 66b461522b..bed4355aa9 100644 --- a/src/network/socket/qlocalsocket_win.cpp +++ b/src/network/socket/qlocalsocket_win.cpp @@ -107,6 +107,7 @@ QLocalSocketPrivate::QLocalSocketPrivate() : QIODevicePrivate(), error(QLocalSocket::UnknownSocketError), state(QLocalSocket::UnconnectedState) { + writeBufferChunkSize = QIODEVICE_BUFFERSIZE; } QLocalSocketPrivate::~QLocalSocketPrivate() @@ -214,8 +215,7 @@ qint64 QLocalSocket::writeData(const char *data, qint64 len) Q_D(QLocalSocket); if (len == 0) return 0; - char *dest = d->writeBuffer.reserve(len); - memcpy(dest, data, len); + d->writeBuffer.append(data, len); if (!d->pipeWriter) { d->pipeWriter = new QWindowsPipeWriter(d->handle, this); connect(d->pipeWriter, &QWindowsPipeWriter::bytesWritten, @@ -233,7 +233,6 @@ void QLocalSocket::abort() if (d->pipeWriter) { delete d->pipeWriter; d->pipeWriter = 0; - d->writeBuffer.clear(); } close(); } @@ -291,6 +290,7 @@ void QLocalSocket::close() if (openMode() == NotOpen) return; + d->setWriteChannelCount(0); QIODevice::close(); d->serverName = QString(); d->fullServerName = QString(); diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp index 18f90a8a4e..181c49f200 100644 --- a/src/network/socket/qnativesocketengine_winrt.cpp +++ b/src/network/socket/qnativesocketengine_winrt.cpp @@ -464,17 +464,24 @@ void QNativeSocketEngine::close() } #if _MSC_VER >= 1900 - // To close the connection properly (not with a hard reset) all pending read operation have to - // be finished or cancelled. The API isn't available on Windows 8.1 though. - ComPtr<IStreamSocket3> socket3; - hr = d->tcpSocket()->QueryInterface(IID_PPV_ARGS(&socket3)); - Q_ASSERT_SUCCEEDED(hr); + if (d->socketType == QAbstractSocket::TcpSocket) { + hr = QEventDispatcherWinRT::runOnXamlThread([d]() { + HRESULT hr; + // To close the connection properly (not with a hard reset) all pending read operation have to + // be finished or cancelled. The API isn't available on Windows 8.1 though. + ComPtr<IStreamSocket3> socket3; + hr = d->tcpSocket()->QueryInterface(IID_PPV_ARGS(&socket3)); + Q_ASSERT_SUCCEEDED(hr); - ComPtr<IAsyncAction> action; - hr = socket3->CancelIOAsync(&action); - Q_ASSERT_SUCCEEDED(hr); - hr = QWinRTFunctions::await(action); - Q_ASSERT_SUCCEEDED(hr); + ComPtr<IAsyncAction> action; + hr = socket3->CancelIOAsync(&action); + Q_ASSERT_SUCCEEDED(hr); + hr = QWinRTFunctions::await(action); + Q_ASSERT_SUCCEEDED(hr); + return S_OK; + }); + Q_ASSERT_SUCCEEDED(hr); + } #endif // _MSC_VER >= 1900 if (d->readOp) { @@ -1271,9 +1278,12 @@ void QNativeSocketEnginePrivate::handleConnectionEstablished(IAsyncAction *actio HRESULT QNativeSocketEnginePrivate::handleReadyRead(IAsyncBufferOperation *asyncInfo, AsyncStatus status) { - Q_Q(QNativeSocketEngine); - if (wasDeleted || isDeletingChildren) + if (closingDown || wasDeleted || isDeletingChildren + || socketState == QAbstractSocket::UnconnectedState) { return S_OK; + } + + Q_Q(QNativeSocketEngine); // A read in UnconnectedState will close the socket and return -1 and thus tell the caller, // that the connection was closed. The socket cannot be closed here, as the subsequent read diff --git a/src/network/socket/qnativesocketengine_winrt_p.h b/src/network/socket/qnativesocketengine_winrt_p.h index 2c4d439a29..325e4965e6 100644 --- a/src/network/socket/qnativesocketengine_winrt_p.h +++ b/src/network/socket/qnativesocketengine_winrt_p.h @@ -154,7 +154,7 @@ public: qintptr socketDescriptor; bool notifyOnRead, notifyOnWrite, notifyOnException; - bool closingDown; + QAtomicInt closingDown; enum ErrorString { NonBlockingInitFailedErrorString, diff --git a/src/network/ssl/qsslconfiguration.cpp b/src/network/ssl/qsslconfiguration.cpp index f9bb28e033..c8040dec7f 100644 --- a/src/network/ssl/qsslconfiguration.cpp +++ b/src/network/ssl/qsslconfiguration.cpp @@ -211,6 +211,7 @@ bool QSslConfiguration::operator==(const QSslConfiguration &other) const d->sessionProtocol == other.d->sessionProtocol && d->ciphers == other.d->ciphers && d->ellipticCurves == other.d->ellipticCurves && + d->ephemeralServerKey == other.d->ephemeralServerKey && d->caCertificates == other.d->caCertificates && d->protocol == other.d->protocol && d->peerVerifyMode == other.d->peerVerifyMode && @@ -252,6 +253,7 @@ bool QSslConfiguration::isNull() const d->caCertificates.count() == 0 && d->ciphers.count() == 0 && d->ellipticCurves.isEmpty() && + d->ephemeralServerKey.isNull() && d->localCertificateChain.isEmpty() && d->privateKey.isNull() && d->peerCertificate.isNull() && diff --git a/src/network/ssl/qsslconfiguration_p.h b/src/network/ssl/qsslconfiguration_p.h index 093c9d6598..364bba92ec 100644 --- a/src/network/ssl/qsslconfiguration_p.h +++ b/src/network/ssl/qsslconfiguration_p.h @@ -88,6 +88,7 @@ public: peerSessionShared(false), sslOptions(QSslConfigurationPrivate::defaultSslOptions), sslSessionTicketLifeTimeHint(-1), + ephemeralServerKey(), nextProtocolNegotiationStatus(QSslConfiguration::NextProtocolNegotiationNone) { } |