mirror of
https://github.com/nextcloud/desktop.git
synced 2024-11-24 14:05:58 +03:00
Proxy: Look up system proxy from different thread
We should actually upstream this into QNAM. This is for #2993 and #2802
This commit is contained in:
parent
99734f8d72
commit
83c3d76966
5 changed files with 98 additions and 3 deletions
|
@ -145,6 +145,9 @@ void OwncloudSetupWizard::slotDetermineAuthType(const QString &urlString)
|
||||||
}
|
}
|
||||||
AccountPtr account = _ocWizard->account();
|
AccountPtr account = _ocWizard->account();
|
||||||
account->setUrl(url);
|
account->setUrl(url);
|
||||||
|
// Reset the proxy which might had been determined previously in ConnectionValidator::checkServerAndAuth()
|
||||||
|
// when there was a previous account.
|
||||||
|
account->networkAccessManager()->setProxy(QNetworkProxy(QNetworkProxy::DefaultProxy));
|
||||||
// Set fake credentials beforfe we check what credential it actually is.
|
// Set fake credentials beforfe we check what credential it actually is.
|
||||||
account->setCredentials(CredentialsFactory::create("dummy"));
|
account->setCredentials(CredentialsFactory::create("dummy"));
|
||||||
CheckServerJob *job = new CheckServerJob(_ocWizard->account(), this);
|
CheckServerJob *job = new CheckServerJob(_ocWizard->account(), this);
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
#include "configfile.h"
|
#include "configfile.h"
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
#include <QThreadPool>
|
||||||
|
|
||||||
namespace OCC {
|
namespace OCC {
|
||||||
|
|
||||||
|
@ -23,7 +24,7 @@ ClientProxy::ClientProxy(QObject *parent) :
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
QNetworkProxy ClientProxy::proxyFromConfig(const ConfigFile& cfg)
|
static QNetworkProxy proxyFromConfig(const ConfigFile& cfg)
|
||||||
{
|
{
|
||||||
QNetworkProxy proxy;
|
QNetworkProxy proxy;
|
||||||
|
|
||||||
|
@ -39,6 +40,17 @@ QNetworkProxy ClientProxy::proxyFromConfig(const ConfigFile& cfg)
|
||||||
return proxy;
|
return proxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ClientProxy::isUsingSystemDefault() {
|
||||||
|
OCC::ConfigFile cfg;
|
||||||
|
|
||||||
|
// if there is no config file, default to system proxy.
|
||||||
|
if( cfg.exists() ) {
|
||||||
|
return cfg.proxyType() == QNetworkProxy::DefaultProxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void ClientProxy::setupQtProxyFromConfig()
|
void ClientProxy::setupQtProxyFromConfig()
|
||||||
{
|
{
|
||||||
OCC::ConfigFile cfg;
|
OCC::ConfigFile cfg;
|
||||||
|
@ -57,15 +69,18 @@ void ClientProxy::setupQtProxyFromConfig()
|
||||||
QNetworkProxy::setApplicationProxy(QNetworkProxy::NoProxy);
|
QNetworkProxy::setApplicationProxy(QNetworkProxy::NoProxy);
|
||||||
break;
|
break;
|
||||||
case QNetworkProxy::DefaultProxy:
|
case QNetworkProxy::DefaultProxy:
|
||||||
|
qDebug() << "Set proxy configuration to use system configuration";
|
||||||
QNetworkProxyFactory::setUseSystemConfiguration(true);
|
QNetworkProxyFactory::setUseSystemConfiguration(true);
|
||||||
break;
|
break;
|
||||||
case QNetworkProxy::Socks5Proxy:
|
case QNetworkProxy::Socks5Proxy:
|
||||||
proxy.setType(QNetworkProxy::Socks5Proxy);
|
proxy.setType(QNetworkProxy::Socks5Proxy);
|
||||||
|
qDebug() << "Set proxy configuration to SOCKS5" << proxy;
|
||||||
QNetworkProxyFactory::setUseSystemConfiguration(false);
|
QNetworkProxyFactory::setUseSystemConfiguration(false);
|
||||||
QNetworkProxy::setApplicationProxy(proxy);
|
QNetworkProxy::setApplicationProxy(proxy);
|
||||||
break;
|
break;
|
||||||
case QNetworkProxy::HttpProxy:
|
case QNetworkProxy::HttpProxy:
|
||||||
proxy.setType(QNetworkProxy::HttpProxy);
|
proxy.setType(QNetworkProxy::HttpProxy);
|
||||||
|
qDebug() << "Set proxy configuration to HTTP" << proxy;
|
||||||
QNetworkProxyFactory::setUseSystemConfiguration(false);
|
QNetworkProxyFactory::setUseSystemConfiguration(false);
|
||||||
QNetworkProxy::setApplicationProxy(proxy);
|
QNetworkProxy::setApplicationProxy(proxy);
|
||||||
break;
|
break;
|
||||||
|
@ -96,6 +111,7 @@ const char* ClientProxy::proxyTypeToCStr(QNetworkProxy::ProxyType type)
|
||||||
|
|
||||||
void ClientProxy::setCSyncProxy( const QUrl& url, CSYNC *csync_ctx )
|
void ClientProxy::setCSyncProxy( const QUrl& url, CSYNC *csync_ctx )
|
||||||
{
|
{
|
||||||
|
#ifdef USE_NEON
|
||||||
/* Store proxy */
|
/* Store proxy */
|
||||||
QList<QNetworkProxy> proxies = QNetworkProxyFactory::proxyForQuery(QNetworkProxyQuery(url));
|
QList<QNetworkProxy> proxies = QNetworkProxyFactory::proxyForQuery(QNetworkProxyQuery(url));
|
||||||
// We set at least one in Application
|
// We set at least one in Application
|
||||||
|
@ -118,7 +134,36 @@ void ClientProxy::setCSyncProxy( const QUrl& url, CSYNC *csync_ctx )
|
||||||
csync_set_module_property( csync_ctx, "proxy_port", &proxy_port );
|
csync_set_module_property( csync_ctx, "proxy_port", &proxy_port );
|
||||||
csync_set_module_property( csync_ctx, "proxy_user", proxy.user().toUtf8().data());
|
csync_set_module_property( csync_ctx, "proxy_user", proxy.user().toUtf8().data());
|
||||||
csync_set_module_property( csync_ctx, "proxy_pwd", proxy.password().toUtf8().data());
|
csync_set_module_property( csync_ctx, "proxy_pwd", proxy.password().toUtf8().data());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void ClientProxy::lookupSystemProxyAsync(const QUrl &url, QObject *dst, const char *slot)
|
||||||
|
{
|
||||||
|
SystemProxyRunnable *runnable = new SystemProxyRunnable(url);
|
||||||
|
QObject::connect(runnable, SIGNAL(systemProxyLookedUp(QNetworkProxy)), dst, slot);
|
||||||
|
QThreadPool::globalInstance()->start(runnable); // takes ownership and deletes
|
||||||
|
}
|
||||||
|
|
||||||
|
SystemProxyRunnable::SystemProxyRunnable(const QUrl &url) : QObject(), QRunnable(), _url(url)
|
||||||
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SystemProxyRunnable::run()
|
||||||
|
{
|
||||||
|
qDebug() << Q_FUNC_INFO << "Starting system proxy lookup";
|
||||||
|
QList<QNetworkProxy> proxies = QNetworkProxyFactory::systemProxyForQuery(QNetworkProxyQuery(_url));
|
||||||
|
qDebug() << Q_FUNC_INFO << proxies.count() << "proxies: " << proxies;
|
||||||
|
|
||||||
|
if (proxies.isEmpty()) {
|
||||||
|
emit systemProxyLookedUp(QNetworkProxy(QNetworkProxy::NoProxy));
|
||||||
|
} else {
|
||||||
|
emit systemProxyLookedUp(proxies.first());
|
||||||
|
// FIXME Would we really ever return more?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QNetworkProxy>
|
#include <QNetworkProxy>
|
||||||
|
#include <QRunnable>
|
||||||
|
|
||||||
#include <csync.h>
|
#include <csync.h>
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
|
@ -30,17 +31,28 @@ class OWNCLOUDSYNC_EXPORT ClientProxy : public QObject
|
||||||
public:
|
public:
|
||||||
explicit ClientProxy(QObject *parent = 0);
|
explicit ClientProxy(QObject *parent = 0);
|
||||||
|
|
||||||
signals:
|
static bool isUsingSystemDefault();
|
||||||
|
static void lookupSystemProxyAsync(const QUrl &url, QObject *dst, const char *slot);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setCSyncProxy( const QUrl& url, CSYNC *csync_ctx );
|
void setCSyncProxy( const QUrl& url, CSYNC *csync_ctx );
|
||||||
void setupQtProxyFromConfig();
|
void setupQtProxyFromConfig();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QNetworkProxy proxyFromConfig(const ConfigFile& cfg);
|
|
||||||
const char* proxyTypeToCStr(QNetworkProxy::ProxyType type);
|
const char* proxyTypeToCStr(QNetworkProxy::ProxyType type);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SystemProxyRunnable : public QObject, public QRunnable {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
SystemProxyRunnable(const QUrl &url);
|
||||||
|
void run();
|
||||||
|
signals:
|
||||||
|
void systemProxyLookedUp(const QNetworkProxy &url);
|
||||||
|
private:
|
||||||
|
QUrl _url;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // CLIENTPROXY_H
|
#endif // CLIENTPROXY_H
|
||||||
|
|
|
@ -13,11 +13,13 @@
|
||||||
|
|
||||||
#include <QtCore>
|
#include <QtCore>
|
||||||
#include <QNetworkReply>
|
#include <QNetworkReply>
|
||||||
|
#include <QNetworkProxyFactory>
|
||||||
|
|
||||||
#include "connectionvalidator.h"
|
#include "connectionvalidator.h"
|
||||||
#include "theme.h"
|
#include "theme.h"
|
||||||
#include "account.h"
|
#include "account.h"
|
||||||
#include "networkjobs.h"
|
#include "networkjobs.h"
|
||||||
|
#include "clientproxy.h"
|
||||||
#include <creds/abstractcredentials.h>
|
#include <creds/abstractcredentials.h>
|
||||||
|
|
||||||
namespace OCC {
|
namespace OCC {
|
||||||
|
@ -63,6 +65,34 @@ void ConnectionValidator::checkServerAndAuth()
|
||||||
}
|
}
|
||||||
_isCheckingServerAndAuth = true;
|
_isCheckingServerAndAuth = true;
|
||||||
|
|
||||||
|
// Lookup system proxy in a thread https://github.com/owncloud/client/issues/2993
|
||||||
|
if (ClientProxy::isUsingSystemDefault()) {
|
||||||
|
qDebug() << "Trying to look up system proxy";
|
||||||
|
ClientProxy::lookupSystemProxyAsync(_account->url(),
|
||||||
|
this, SLOT(systemProxyLookupDone(QNetworkProxy)));
|
||||||
|
} else {
|
||||||
|
// use a queued invocation so we're as asynchronous as with the other code path
|
||||||
|
QMetaObject::invokeMethod(this, "slotCheckServerAndAuth", Qt::QueuedConnection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConnectionValidator::systemProxyLookupDone(const QNetworkProxy &proxy) {
|
||||||
|
if (!_account) {
|
||||||
|
qDebug() << "Bailing out, Account had been deleted";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (proxy.type() != QNetworkProxy::DefaultProxy) {
|
||||||
|
qDebug() << Q_FUNC_INFO << "Setting QNAM proxy to be system proxy" << proxy;
|
||||||
|
_account->networkAccessManager()->setProxy(proxy);
|
||||||
|
}
|
||||||
|
|
||||||
|
slotCheckServerAndAuth();
|
||||||
|
}
|
||||||
|
|
||||||
|
// The actual check
|
||||||
|
void ConnectionValidator::slotCheckServerAndAuth()
|
||||||
|
{
|
||||||
CheckServerJob *checkJob = new CheckServerJob(_account, this);
|
CheckServerJob *checkJob = new CheckServerJob(_account, this);
|
||||||
checkJob->setIgnoreCredentialFailure(true);
|
checkJob->setIgnoreCredentialFailure(true);
|
||||||
connect(checkJob, SIGNAL(instanceFound(QUrl,QVariantMap)), SLOT(slotStatusFound(QUrl,QVariantMap)));
|
connect(checkJob, SIGNAL(instanceFound(QUrl,QVariantMap)), SLOT(slotStatusFound(QUrl,QVariantMap)));
|
||||||
|
|
|
@ -36,6 +36,8 @@ namespace OCC {
|
||||||
|
|
||||||
|
|
||||||
*---> checkServerAndAuth (check status.php)
|
*---> checkServerAndAuth (check status.php)
|
||||||
|
Will asynchronously check for system proxy (if using system proxy)
|
||||||
|
And then invoke slotCheckServerAndAuth
|
||||||
CheckServerJob
|
CheckServerJob
|
||||||
|
|
|
|
||||||
+-> slotNoStatusFound --> X
|
+-> slotNoStatusFound --> X
|
||||||
|
@ -85,6 +87,7 @@ public:
|
||||||
public slots:
|
public slots:
|
||||||
/// Checks the server and the authentication.
|
/// Checks the server and the authentication.
|
||||||
void checkServerAndAuth();
|
void checkServerAndAuth();
|
||||||
|
void systemProxyLookupDone(const QNetworkProxy &proxy);
|
||||||
|
|
||||||
/// Checks authentication only.
|
/// Checks authentication only.
|
||||||
void checkAuthentication();
|
void checkAuthentication();
|
||||||
|
@ -93,6 +96,8 @@ signals:
|
||||||
void connectionResult( ConnectionValidator::Status status, QStringList errors );
|
void connectionResult( ConnectionValidator::Status status, QStringList errors );
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
|
void slotCheckServerAndAuth();
|
||||||
|
|
||||||
void slotStatusFound(const QUrl&url, const QVariantMap &info);
|
void slotStatusFound(const QUrl&url, const QVariantMap &info);
|
||||||
void slotNoStatusFound(QNetworkReply *reply);
|
void slotNoStatusFound(QNetworkReply *reply);
|
||||||
void slotJobTimeout(const QUrl& url);
|
void slotJobTimeout(const QUrl& url);
|
||||||
|
|
Loading…
Reference in a new issue