SSL internals: do not write after shutting down the socket
... but rather throw an error, so the HTTP layer can recover from a SSL shutdown gracefully. In case the other side sent us a shutdown, we should not send one as well, as it results in an error. Change-Id: Ie7a56cf3008b6ead912aade18dbec67846e2a87e Reviewed-by: Richard J. Moore <rich@kde.org>bb10
parent
3467320378
commit
e145b67fbd
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,6 +109,7 @@ public:
|
|||
QSslSocket::SslMode mode;
|
||||
bool autoStartHandshake;
|
||||
bool connectionEncrypted;
|
||||
bool shutdown;
|
||||
bool ignoreAllSslErrors;
|
||||
QList<QSslError> ignoreErrorsList;
|
||||
bool* readyReadEmittedPointer;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue