diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ project(konversation) cmake_minimum_required (VERSION 2.8.12 FATAL_ERROR) -set (QT_MIN_VERSION "5.5.0") +set (QT_MIN_VERSION "5.7.0") set(KF5_MIN_VERSION "5.25.0") find_package(ECM ${KF5_MIN_VERSION} REQUIRED NO_MODULE) @@ -14,7 +14,7 @@ include(ECMInstallIcons) include(FeatureSummary) -find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED Core Widgets) +find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED Core Network Widgets) find_package(KF5 ${KF5_MIN_VERSION} REQUIRED Archive diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -218,6 +218,7 @@ add_executable(konversation ${konversation_SRCS}) target_link_libraries(konversation + Qt5::Network Qt5::Widgets KF5::Archive KF5::Bookmarks diff --git a/src/irc/server.h b/src/irc/server.h --- a/src/irc/server.h +++ b/src/irc/server.h @@ -36,10 +36,10 @@ #include #include +#include #include #include -#include #include class QAbstractItemModel; @@ -573,11 +573,11 @@ void toServer(QString&, IRCQueue *); /// Because KBufferedSocket has no closed(int) signal we use this slot to call broken(0) void closed(); - void broken(KTcpSocket::Error error); + void broken(QAbstractSocket::SocketError error); /** This is connected to the SSLSocket failed. * @param reason The reason why this failed. This is already translated, ready to show the user. */ - void sslError(const QList&); + void sslError(const QList&); void connectionEstablished(const QString& ownHost); void notifyResponse(const QString& nicksOnline); @@ -738,7 +738,7 @@ QStringList m_autoJoinCommands; - KTcpSocket* m_socket; + QSslSocket *m_socket; QTimer m_incomingTimer; QTimer m_notifyTimer; diff --git a/src/irc/server.cpp b/src/irc/server.cpp --- a/src/irc/server.cpp +++ b/src/irc/server.cpp @@ -40,6 +40,7 @@ #include "ircinput.h" #include +#include #include #include #include @@ -50,6 +51,7 @@ #include #include +#include #include using namespace Konversation; @@ -466,48 +468,59 @@ m_nickListModel->setStringList(getIdentity()->getNicknameList()); resetNickSelection(); - m_socket = new KTcpSocket(); + m_socket = new QSslSocket(); m_socket->setObjectName(QStringLiteral("serverSocket")); - connect(m_socket, SIGNAL(error(KTcpSocket::Error)), SLOT(broken(KTcpSocket::Error)) ); - connect(m_socket, &QIODevice::readyRead, this, &Server::incoming); - connect(m_socket, &KTcpSocket::disconnected, this, &Server::closed); + connect(m_socket, QOverload::of(&QAbstractSocket::error), + this, &Server::broken); - connect(m_socket, &KTcpSocket::hostFound, this, &Server::hostFound); + connect(m_socket, &QIODevice::readyRead, this, &Server::incoming); + connect(m_socket, &QAbstractSocket::disconnected, this, &Server::closed); + connect(m_socket, &QAbstractSocket::hostFound, this, &Server::hostFound); getStatusView()->appendServerMessage(i18n("Info"),i18n("Looking for server %1 (port %2)...", getConnectionSettings().server().host(), QString::number(getConnectionSettings().server().port()))); - KTcpSocket::ProxyPolicy proxyPolicy = KTcpSocket::AutoProxy; if(getConnectionSettings().server().bypassProxy()) { - proxyPolicy = KTcpSocket::ManualProxy; m_socket->setProxy(QNetworkProxy::NoProxy); } // connect() will do a async lookup too if (getConnectionSettings().server().SSLEnabled() || getIdentity()->getAuthType() == QLatin1String("saslexternal") || getIdentity()->getAuthType() == QLatin1String("pemclientcert")) { - connect(m_socket, &KTcpSocket::encrypted, this, &Server::socketConnected); - connect(m_socket, SIGNAL(sslErrors(QList)), SLOT(sslError(QList))); + connect(m_socket, &QSslSocket::encrypted, this, &Server::socketConnected); + connect(m_socket, QOverload &>::of(&QSslSocket::sslErrors), + this, &Server::sslError); if (getIdentity()->getAuthType() == QLatin1String("saslexternal") || getIdentity()->getAuthType() == QLatin1String("pemclientcert")) { m_socket->setLocalCertificate(getIdentity()->getPemClientCertFile().toLocalFile()); m_socket->setPrivateKey(getIdentity()->getPemClientCertFile().toLocalFile()); } - m_socket->setAdvertisedSslVersion(KTcpSocket::SecureProtocols); - - m_socket->connectToHostEncrypted(getConnectionSettings().server().host(), getConnectionSettings().server().port()); + m_socket->setProtocol(QSsl::SecureProtocols); + // QIODevice::Unbuffered, see m_socket->connectToHost() call below + m_socket->connectToHostEncrypted(getConnectionSettings().server().host(), + getConnectionSettings().server().port(), + (QIODevice::ReadWrite | QIODevice::Unbuffered)); } else { - connect(m_socket, &KTcpSocket::connected, this, &Server::socketConnected); - m_socket->connectToHost(getConnectionSettings().server().host(), getConnectionSettings().server().port(), proxyPolicy); + connect(m_socket, &QAbstractSocket::connected, this, &Server::socketConnected); + // From KTcpSocket::connectToHost(): + // There are enough layers of buffers between us and the network, and there is a quirk + // in QIODevice that can make it try to readData() twice per read() call if buffered and + // reaData() does not deliver enough data the first time. Like when the other side is + // simply not sending any more data... + // This can *apparently* lead to long delays sometimes which stalls applications. + // Do not want. + m_socket->connectToHost(getConnectionSettings().server().host(), + getConnectionSettings().server().port(), + (QIODevice::ReadWrite | QIODevice::Unbuffered)); } // set up the connection details @@ -860,7 +873,7 @@ } } -void Server::broken(KTcpSocket::Error error) +void Server::broken(QAbstractSocket::SocketError error) { Q_UNUSED(error); qDebug() << "Connection broken with state" << m_connectionState << "and error:" << m_socket->errorString(); @@ -935,16 +948,17 @@ } -void Server::sslError( const QList& errors ) +void Server::sslError(const QList &errors) { // We have to explicitly grab the socket we got the error from, // lest we might end up calling ignoreSslErrors() on a different // socket later if m_socket has started pointing at something // else. - QPointer socket = qobject_cast(QObject::sender()); + QPointer socket = qobject_cast(QObject::sender()); m_sslErrorLock = true; - bool ignoreSslErrors = KIO::SslUi::askIgnoreSslErrors(socket, KIO::SslUi::RecallAndStoreRules); + KSslErrorUiData uiData(socket); + bool ignoreSslErrors = KIO::SslUi::askIgnoreSslErrors(uiData, KIO::SslUi::RecallAndStoreRules); m_sslErrorLock = false; // The dialog-based user interaction above may take an undefined amount @@ -1066,7 +1080,7 @@ { if (!m_socket) return false; - return (m_socket->state() == KTcpSocket::ConnectedState); + return (m_socket->state() == QAbstractSocket::ConnectedState); } void Server::updateConnectionState(Konversation::ConnectionState state) @@ -3974,7 +3988,7 @@ bool Server::getUseSSL() const { if ( m_socket ) - return ( m_socket->encryptionMode() != KTcpSocket::UnencryptedMode ); + return ( m_socket->mode() != QSslSocket::UnencryptedMode ); else return false; }