diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.5) -set(PIM_VERSION "5.11.40") +set(PIM_VERSION "5.11.41") project(KIMAP VERSION ${PIM_VERSION}) diff --git a/src/session.h b/src/session.h --- a/src/session.h +++ b/src/session.h @@ -91,6 +91,18 @@ */ Q_REQUIRED_RESULT QString selectedMailBox() const; + /** + * Sets whether the IMAP network connection should use the system proxy settings. + * + * @param useProxy @c true if the proxy is to be used + * The default is to not use the proxy. + * @since 5.11.41 + * + * @note If the session is currently connected to the IMAP server, calling this + * function will disconnect and reconnect to it with the changed proxy setting. + */ + void setUseNetworkProxy(bool useProxy); + Q_REQUIRED_RESULT int jobQueueSize() const; void close(); diff --git a/src/session.cpp b/src/session.cpp --- a/src/session.cpp +++ b/src/session.cpp @@ -98,6 +98,11 @@ return d->thread->port(); } +void Session::setUseNetworkProxy(bool useProxy) +{ + d->thread->setUseNetworkProxy(useProxy); +} + Session::State Session::state() const { return d->state; diff --git a/src/sessionthread.cpp b/src/sessionthread.cpp --- a/src/sessionthread.cpp +++ b/src/sessionthread.cpp @@ -21,6 +21,7 @@ #include #include +#include #include "kimap_debug.h" @@ -37,7 +38,8 @@ SessionThread::SessionThread(const QString &hostName, quint16 port) : QObject(), m_hostName(hostName), m_port(port), m_socket(nullptr), m_stream(nullptr), m_mutex(), - m_encryptedMode(false) + m_encryptedMode(false), + m_useProxy(false) { // Just like the Qt docs now recommend, for event-driven threads: // don't derive from QThread, create one directly and move the object to it. @@ -59,6 +61,12 @@ delete thread(); } +// Called in primary thread, passes setting to secondary thread +void SessionThread::setUseNetworkProxy(bool useProxy) +{ + QMetaObject::invokeMethod(this, [this, useProxy]() { setUseProxyInternal(useProxy); }, Qt::QueuedConnection); +} + // Called in primary thread void SessionThread::sendData(const QByteArray &payload) { @@ -162,6 +170,17 @@ } if (m_socket->state() != SessionSocket::ConnectedState && m_socket->state() != SessionSocket::ConnectingState) { + + QNetworkProxy proxy; + if (!m_useProxy) { + qCDebug(KIMAP_LOG) << "Connecting to IMAP server with no proxy"; + proxy.setType(QNetworkProxy::NoProxy); + } else { + qCDebug(KIMAP_LOG) << "Connecting to IMAP server using default system proxy"; + proxy.setType(QNetworkProxy::DefaultProxy); + } + m_socket->setProxy(proxy); + if (m_encryptedMode) { qCDebug(KIMAP_LOG) << "connectToHostEncrypted" << m_hostName << m_port; m_socket->connectToHostEncrypted(m_hostName, m_port); @@ -210,6 +229,18 @@ thread()->quit(); } +// Called in secondary thread +void SessionThread::setUseProxyInternal(bool useProxy) +{ + m_useProxy = useProxy; + if (m_socket != nullptr) { + if (m_socket->state() != SessionSocket::UnconnectedState) { + m_socket->disconnectFromHost(); + QMetaObject::invokeMethod(this, &SessionThread::reconnect, Qt::QueuedConnection); + } + } +} + // Called in primary thread void SessionThread::startSsl(KTcpSocket::SslVersion version) { diff --git a/src/sessionthread_p.h b/src/sessionthread_p.h --- a/src/sessionthread_p.h +++ b/src/sessionthread_p.h @@ -50,6 +50,8 @@ return m_port; } + void setUseNetworkProxy(bool useProxy); + void sendData(const QByteArray &payload); public Q_SLOTS: @@ -78,6 +80,7 @@ void slotSocketDisconnected(); void doStartSsl(KTcpSocket::SslVersion); void doSslErrorHandlerResponse(bool result); + void setUseProxyInternal(bool useProxy); private: QString m_hostName; @@ -92,6 +95,7 @@ QMutex m_mutex; bool m_encryptedMode = false; + bool m_useProxy = false; }; }