From 4d0a8a6030728bcf63b654ecee2de2fec3575b77 Mon Sep 17 00:00:00 2001 From: Michal Klocek Date: Tue, 1 Nov 2022 22:43:34 +0100 Subject: Use QSslServer in certificate test We had our own implementation for the HTTPS server. However, the way it worked involved adding for every incoming connection a socket to the list of pending connections, which resulted in unnecessary logging noise due to socket connect/disconnected signals during the SSL handshake negotiations. It also resulted in memory leaks. Since 6.4 we have now QSslServer which adds socket to the pending connection list only after encryption got established. Pick-to: 6.4 Change-Id: I3c8a2a0684e3f0760a56d4b4aaf7b777700e334b Reviewed-by: Allan Sandfeld Jensen --- .../core/certificateerror/tst_certificateerror.cpp | 3 +- tests/auto/httpserver/httpserver.cpp | 3 +- tests/auto/httpserver/httpsserver.h | 62 ++++++++++------------ 3 files changed, 31 insertions(+), 37 deletions(-) (limited to 'tests') diff --git a/tests/auto/core/certificateerror/tst_certificateerror.cpp b/tests/auto/core/certificateerror/tst_certificateerror.cpp index a37a665a9..9ad2c03ee 100644 --- a/tests/auto/core/certificateerror/tst_certificateerror.cpp +++ b/tests/auto/core/certificateerror/tst_certificateerror.cpp @@ -68,7 +68,7 @@ void tst_CertificateError::handleError_data() void tst_CertificateError::handleError() { HttpsServer server(":/resources/server.pem",":/resources/server.key"); - server.setExpectError(true); + server.setExpectError(false); QVERIFY(server.start()); connect(&server, &HttpsServer::newRequest, [&] (HttpReqRep *rr) { @@ -105,6 +105,7 @@ void tst_CertificateError::handleError() QTRY_COMPARE_WITH_TIMEOUT(page.loadSpy.size(), 1, 30000); QCOMPARE(page.loadSpy.takeFirst().value(0).toBool(), acceptCertificate); QCOMPARE(toPlainTextSync(&page), expectedContent); + QVERIFY(server.stop()); } void tst_CertificateError::fatalError() diff --git a/tests/auto/httpserver/httpserver.cpp b/tests/auto/httpserver/httpserver.cpp index c65d68ce7..e08af77e7 100644 --- a/tests/auto/httpserver/httpserver.cpp +++ b/tests/auto/httpserver/httpserver.cpp @@ -24,7 +24,8 @@ HttpServer::HttpServer(QTcpServer *tcpServer, const QString &protocol, { m_url.setHost(hostAddress.toString()); m_url.setScheme(protocol); - connect(tcpServer, &QTcpServer::newConnection, this, &HttpServer::handleNewConnection); + connect(tcpServer, &QTcpServer::pendingConnectionAvailable, this, + &HttpServer::handleNewConnection); } HttpServer::~HttpServer() diff --git a/tests/auto/httpserver/httpsserver.h b/tests/auto/httpserver/httpsserver.h index d064c1416..2982ed8c4 100644 --- a/tests/auto/httpserver/httpsserver.h +++ b/tests/auto/httpserver/httpsserver.h @@ -7,52 +7,44 @@ #include "httpserver.h" #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include -struct SslTcpServer : QTcpServer +static QSslServer *createServer(const QString &certificateFileName, const QString &keyFileName) { - SslTcpServer(const QString &certPath, const QString &keyPath) { - sslconf.setLocalCertificateChain(QSslCertificate::fromPath(certPath)); - sslconf.setPrivateKey(readKey(keyPath)); - } - - void incomingConnection(qintptr d) override { - auto socket = new QSslSocket(this); - socket->setSslConfiguration(sslconf); - - if (!socket->setSocketDescriptor(d)) { - qWarning() << "Failed to setup ssl socket!"; - delete socket; - return; + QSslConfiguration configuration(QSslConfiguration::defaultConfiguration()); + + QFile keyFile(keyFileName); + if (keyFile.open(QIODevice::ReadOnly)) { + QSslKey key(keyFile.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey); + if (!key.isNull()) { + configuration.setPrivateKey(key); + } else { + qCritical() << "Could not parse key: " << keyFileName; } - - connect(socket, QOverload::of(&QSslSocket::errorOccurred), - [] (QSslSocket::SocketError e) { qWarning() << "! Socket Error:" << e; }); - connect(socket, QOverload &>::of(&QSslSocket::sslErrors), - [] (const QList &le) { qWarning() << "! SSL Errors:\n" << le; }); - - addPendingConnection(socket); - socket->startServerEncryption(); + } else { + qCritical() << "Could not find key: " << keyFileName; } - QSslKey readKey(const QString &path) const { - QFile file(path); - file.open(QIODevice::ReadOnly); - return QSslKey(file.readAll(), QSsl::Rsa, QSsl::Pem); + QList localCerts = QSslCertificate::fromPath(certificateFileName); + if (!localCerts.isEmpty()) { + configuration.setLocalCertificateChain(localCerts); + } else { + qCritical() << "Could not find certificate: " << certificateFileName; } - QSslConfiguration sslconf; -}; + QSslServer *server = new QSslServer(); + server->setSslConfiguration(configuration); + return server; +} struct HttpsServer : HttpServer { HttpsServer(const QString &certPath, const QString &keyPath, QObject *parent = nullptr) - : HttpServer(new SslTcpServer(certPath, keyPath), "https", QHostAddress::LocalHost, 0, - parent) + : HttpServer(createServer(certPath, keyPath), "https", QHostAddress::LocalHost, 0, parent) { } }; -- cgit v1.2.3