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:
Markus Goetz 2015-03-24 21:30:42 +01:00
parent 99734f8d72
commit 83c3d76966
5 changed files with 98 additions and 3 deletions

View file

@ -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);

View file

@ -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?
}
}
} }

View file

@ -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

View file

@ -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)));

View file

@ -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);