diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index a8bf8f83b8..f2310356df 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -1908,6 +1908,7 @@ QSslSocketPrivate::QSslSocketPrivate() , mode(QSslSocket::UnencryptedMode) , autoStartHandshake(false) , connectionEncrypted(false) + , shutdown(false) , ignoreAllSslErrors(false) , readyReadEmittedPointer(0) , allowRootCertOnDemandLoading(true) @@ -1933,6 +1934,7 @@ void QSslSocketPrivate::init() autoStartHandshake = false; connectionEncrypted = false; ignoreAllSslErrors = false; + shutdown = false; // we don't want to clear the ignoreErrorsList, so // that it is possible setting it before connecting diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index 3b2de7a05b..d515f27865 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -934,8 +934,11 @@ void QSslSocketBackendPrivate::transmit() #ifdef QSSLSOCKET_DEBUG qDebug() << "QSslSocketBackendPrivate::transmit: remote disconnect"; #endif - plainSocket->disconnectFromHost(); - break; + shutdown = true; // the other side shut down, make sure we do not send shutdown ourselves + q->setErrorString(QSslSocket::tr("The TLS/SSL connection has been closed")); + q->setSocketError(QAbstractSocket::RemoteHostClosedError); + emit q->error(QAbstractSocket::RemoteHostClosedError); + return; case SSL_ERROR_SYSCALL: // some IO error case SSL_ERROR_SSL: // error in the SSL library // we do not know exactly what the error is, nor whether we can recover from it, @@ -1369,8 +1372,11 @@ void QWindowsCaRootFetcher::start() void QSslSocketBackendPrivate::disconnectFromHost() { if (ssl) { - q_SSL_shutdown(ssl); - transmit(); + if (!shutdown) { + q_SSL_shutdown(ssl); + shutdown = true; + transmit(); + } } plainSocket->disconnectFromHost(); } diff --git a/src/network/ssl/qsslsocket_p.h b/src/network/ssl/qsslsocket_p.h index 72117353ac..d1d79ae09c 100644 --- a/src/network/ssl/qsslsocket_p.h +++ b/src/network/ssl/qsslsocket_p.h @@ -109,6 +109,7 @@ public: QSslSocket::SslMode mode; bool autoStartHandshake; bool connectionEncrypted; + bool shutdown; bool ignoreAllSslErrors; QList ignoreErrorsList; bool* readyReadEmittedPointer; diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp index feb6978690..f3adb2b52f 100644 --- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp @@ -2135,7 +2135,8 @@ void tst_QSslSocket::writeBigChunk() QFAIL("Error while writing! Check if the OpenSSL BIO size is limited?!"); } // also check the error string. If another error (than UnknownError) occurred, it should be different than before - QVERIFY(errorBefore == errorAfter); + QVERIFY2(errorBefore == errorAfter || socket->error() == QAbstractSocket::RemoteHostClosedError, + QByteArray("unexpected error: ").append(qPrintable(errorAfter))); // check that everything has been written to OpenSSL QVERIFY(socket->bytesToWrite() == 0);